<?php
SUBWAY => 'едешь на метро' ,
FOOT => 'идешь пешком' ,
BUS => 'едешь на автобусе'
) ;
$startPoint = 'pet' ; // Петроградская
$endPoint = 'nov' ; // Новая Голландия
'pet' => 'ст. м. Петроградская' ,
'chk' => 'ст. м. Чкаловская' ,
'gor' => 'ст. м. Горьковская' ,
'spo' => 'ст. м. Спортивная' ,
'vas' => 'ст. м. Василеостровская' ,
'kre' => 'Петропавловская крепость' ,
'let' => 'Летний сад' ,
'dvo' => 'Дворцовая площадь' ,
'isa' => 'Исакиевский собор' ,
'nov' => 'Новая Голландия' ,
'ras' => 'Дом Раскольникова' ,
'gos' => 'Гостиный Двор' ,
'sen' => 'Сенная Площадь' ,
'vla' => 'ст. м. Владимирская' ,
'vit' => 'Витебский вокзал' ,
'teh' => 'Технологический Институт'
) ;
'chk' => canGet( 10 , BUS) ,
'gor' => canGet( 3 , SUBWAY)
) ,
'pet' => canGet( 10 , BUS) ,
'spo' => canGet( 3 , SUBWAY)
) ,
'pet' => canGet( 3 , BUS) ,
'kre' => canGet( 5 , FOOT) ,
'gos' => canGet( 6 , SUBWAY)
) ,
'chk' => canGet( 3 , SUBWAY) ,
'vas' => canGet( 10 , BUS) ,
'sen' => canGet( 7 , SUBWAY)
) ,
'spo' => canGet( 10 , BUS) ,
'gos' => canGet( 7 , SUBWAY) ,
'nov' => canGet( 11 , FOOT)
) ,
'gor' => canGet( 5 , FOOT)
) ,
'dvo' => canGet( 6 , FOOT) ,
'gos' => canGet( 7 , FOOT)
) ,
'isa' => canGet( 6 , FOOT) ,
'gos' => canGet( 6 , FOOT) ,
'let' => canGet( 6 , FOOT)
) ,
'dvo' => canGet( 6 , FOOT) ,
'nov' => canGet( 5 , FOOT)
) ,
'vas' => canGet( 11 , FOOT) ,
'isa' => canGet( 5 , FOOT) ,
'ras' => canGet( 7 , BUS)
) ,
'nov' => canGet( 7 , BUS) ,
'sen' => canGet( 3 , FOOT)
) ,
'vas' => canGet( 7 , SUBWAY) ,
'sen' => canGet( 3 , SUBWAY) ,
'dvo' => canGet( 6 , FOOT) ,
'gor' => canGet( 6 , SUBWAY) ,
'let' => canGet( 7 , FOOT) ,
'vla' => canGet( 7 , FOOT)
) ,
'ras' => canGet( 3 , FOOT) ,
'spo' => canGet( 7 , SUBWAY) ,
'gos' => canGet( 3 , SUBWAY) ,
'vla' => canGet( 4 , SUBWAY) ,
'vit' => canGet( 2 , SUBWAY) ,
'teh' => canGet( 3 , SUBWAY)
) ,
'sen' => canGet( 4 , SUBWAY) ,
'gos' => canGet( 7 , FOOT) ,
'vit' => canGet( 3 , SUBWAY)
) ,
'sen' => canGet( 2 , SUBWAY) ,
'teh' => canGet( 2 , SUBWAY) ,
'vla' => canGet( 3 , SUBWAY)
) ,
'sen' => canGet( 3 , SUBWAY) ,
'vit' => canGet( 2 , SUBWAY)
)
) ;
function canGet( $time , $byWhat )
{
return array ( 'time' => $time , 'by' => $byWhat ) ; }
function initAlgorithm( $paths , $pointNames , $transportName , $startPoint , $endPoint )
{
$paths [ $startPoint ] [ 'label' ] = 0 ;
foreach ( $paths as $point => & $pointValue ) {
if ( $point != $startPoint ) {
$pointValue [ 'label' ] = PHP_INT_MAX;
}
$pointValue [ 'visited' ] = false ;
}
doAlgorithmDeijkstra( $paths , $pointNames , $transportName , $startPoint , $endPoint ) ;
}
function printPaths( $paths , $pointNames , $transportName , $targetPath , $startPoint , $endPoint )
{
echo "Начальная точка: " . $pointNames [ $startPoint ] . "\n " ;
for ( $i = 0 ; $i < count ( $targetPath ) - 1 ; $i ++ ) { $transport = $transportName [ $paths [ $targetPath [ $i ] ] [ $targetPath [ $i + 1 ] ] [ 'by' ] ] ;
echo "Из нее {$transport} до точки " . $pointNames [ $targetPath [ $i + 1 ] ] . " " . $paths [ $targetPath [ $i ] ] [ $targetPath [ $i + 1 ] ] [ 'time' ] . " минут\n " ;
}
echo "В итоге ты попадаешь в точку " . $pointNames [ $endPoint ] . " за " . $paths [ $endPoint ] [ 'label' ] . " минут. Приятной поездки!" ;
}
function searchPath( $paths , $pointName , $transportName , $startPoint , $endPoint )
{
$currentPoint = $endPoint ;
$targetPath = array ( $currentPoint ) ;
while ( $currentPoint != $startPoint ) {
foreach ( $paths [ $currentPoint ] as $point => $pointValue ) {
if ( $point == 'label' || $point == 'visited' ) {
continue ;
}
if ( $paths [ $currentPoint ] [ 'label' ] - $paths [ $currentPoint ] [ $point ] [ 'time' ] == $paths [ $point ] [ 'label' ] ) {
$targetPath [ ] = $point ;
$currentPoint = $point ;
break ;
}
}
}
printPaths( $paths , $pointName , $transportName , $targetPath , $startPoint , $endPoint ) ;
}
function doAlgorithmDeijkstra( $paths , $pointNames , $transportName , $startPoint , $endPoint )
{
$pointCount = count ( $paths ) ;
for ( $i = 0 ; $i < $pointCount ; $i ++ ) {
$minLabel = PHP_INT_MAX;
$pointNameWork = NULL ;
foreach ( $paths as $point => $pointValue ) {
if ( $pointValue [ 'label' ] < $minLabel && ( ! $pointValue [ 'visited' ] ) ) {
$minLabel = $pointValue [ 'label' ] ;
$pointNameWork = $point ;
}
}
$nextPoint = $paths [ $pointNameWork ] ;
foreach ( $nextPoint as $point => $pointValue ) {
continue ;
}
$newLabel = $nextPoint [ 'label' ] + $paths [ $pointNameWork ] [ $point ] [ 'time' ] ;
if ( $paths [ $point ] [ 'label' ] > $newLabel ) {
$paths [ $point ] [ 'label' ] = $newLabel ;
}
}
$paths [ $pointNameWork ] [ 'visited' ] = true ;
}
searchPath( $paths , $pointNames , $transportName , $startPoint , $endPoint ) ;
}
initAlgorithm( $paths , $pointNames , $transportName , $startPoint , $endPoint ) ;
PD9waHAKICAgIGVycm9yX3JlcG9ydGluZygtMSk7CiAgICAKICAgIGRlZmluZSgnU1VCV0FZJywgJ3N1YicpOwogICAgZGVmaW5lKCdGT09UJywgJ2Zvb3QnKTsKICAgIGRlZmluZSgnQlVTJywgJ2J1cycpOwoKICAgICR0cmFuc3BvcnROYW1lID0gYXJyYXkoCiAgICAgICAgU1VCV0FZICA9PiAgJ9C10LTQtdGI0Ywg0L3QsCDQvNC10YLRgNC+JywKICAgICAgICBGT09UICAgID0+ICAn0LjQtNC10YjRjCDQv9C10YjQutC+0LwnLAogICAgICAgIEJVUyAgICAgPT4gICfQtdC00LXRiNGMINC90LAg0LDQstGC0L7QsdGD0YHQtScKICAgICk7CiAgICAgCiAgICAkc3RhcnRQb2ludCA9ICdwZXQnOyAvLyDQn9C10YLRgNC+0LPRgNCw0LTRgdC60LDRjwogICAgJGVuZFBvaW50ID0gJ25vdic7IC8vINCd0L7QstCw0Y8g0JPQvtC70LvQsNC90LTQuNGPCiAgICAgCiAgICAkcG9pbnROYW1lcyA9IGFycmF5KAogICAgICAgICdwZXQnICAgPT4gICfRgdGCLiDQvC4g0J/QtdGC0YDQvtCz0YDQsNC00YHQutCw0Y8nLAogICAgICAgICdjaGsnICAgPT4gICfRgdGCLiDQvC4g0KfQutCw0LvQvtCy0YHQutCw0Y8nLAogICAgICAgICdnb3InICAgPT4gICfRgdGCLiDQvC4g0JPQvtGA0YzQutC+0LLRgdC60LDRjycsCiAgICAgICAgJ3NwbycgICA9PiAgJ9GB0YIuINC8LiDQodC/0L7RgNGC0LjQstC90LDRjycsCiAgICAgICAgJ3ZhcycgICA9PiAgJ9GB0YIuINC8LiDQktCw0YHQuNC70LXQvtGB0YLRgNC+0LLRgdC60LDRjycsCiAgICAgICAgJ2tyZScgICA9PiAgJ9Cf0LXRgtGA0L7Qv9Cw0LLQu9C+0LLRgdC60LDRjyDQutGA0LXQv9C+0YHRgtGMJywKICAgICAgICAnbGV0JyAgID0+ICAn0JvQtdGC0L3QuNC5INGB0LDQtCcsCiAgICAgICAgJ2R2bycgICA9PiAgJ9CU0LLQvtGA0YbQvtCy0LDRjyDQv9C70L7RidCw0LTRjCcsCiAgICAgICAgJ2lzYScgICA9PiAgJ9CY0YHQsNC60LjQtdCy0YHQutC40Lkg0YHQvtCx0L7RgCcsCiAgICAgICAgJ25vdicgICA9PiAgJ9Cd0L7QstCw0Y8g0JPQvtC70LvQsNC90LTQuNGPJywKICAgICAgICAncmFzJyAgID0+ICAn0JTQvtC8INCg0LDRgdC60L7Qu9GM0L3QuNC60L7QstCwJywKICAgICAgICAnZ29zJyAgID0+ICAn0JPQvtGB0YLQuNC90YvQuSDQlNCy0L7RgCcsCiAgICAgICAgJ3NlbicgICA9PiAgJ9Ch0LXQvdC90LDRjyDQn9C70L7RidCw0LTRjCcsCiAgICAgICAgJ3ZsYScgICA9PiAgJ9GB0YIuINC8LiDQktC70LDQtNC40LzQuNGA0YHQutCw0Y8nLAogICAgICAgICd2aXQnICAgPT4gICfQktC40YLQtdCx0YHQutC40Lkg0LLQvtC60LfQsNC7JywKICAgICAgICAndGVoJyAgID0+ICAn0KLQtdGF0L3QvtC70L7Qs9C40YfQtdGB0LrQuNC5INCY0L3RgdGC0LjRgtGD0YInCiAgICApOwogICAgIAogICAgJHBhdGhzID0gYXJyYXkoCiAgICAgICAgJ3BldCcgICA9PiAgYXJyYXkoCiAgICAgICAgICAgICdjaGsnICAgPT4gIGNhbkdldCgxMCwgQlVTKSwKICAgICAgICAgICAgJ2dvcicgICA9PiAgY2FuR2V0KDMsIFNVQldBWSkKICAgICAgICApLAogICAgIAogICAgICAgICdjaGsnICAgPT4gIGFycmF5KAogICAgICAgICAgICAncGV0JyAgID0+ICBjYW5HZXQoMTAsIEJVUyksCiAgICAgICAgICAgICdzcG8nICAgPT4gIGNhbkdldCgzLCBTVUJXQVkpCiAgICAgICAgKSwKICAgICAKICAgICAgICAnZ29yJyAgID0+ICBhcnJheSgKICAgICAgICAgICAgJ3BldCcgICA9PiAgY2FuR2V0KDMsIEJVUyksCiAgICAgICAgICAgICdrcmUnICAgPT4gIGNhbkdldCg1LCBGT09UKSwKICAgICAgICAgICAgJ2dvcycgICA9PiAgY2FuR2V0KDYsIFNVQldBWSkKICAgICAgICApLAogICAgIAogICAgICAgICdzcG8nICAgPT4gIGFycmF5KAogICAgICAgICAgICAnY2hrJyAgID0+ICBjYW5HZXQoMywgU1VCV0FZKSwKICAgICAgICAgICAgJ3ZhcycgICA9PiAgY2FuR2V0KDEwLCBCVVMpLAogICAgICAgICAgICAnc2VuJyAgID0+ICBjYW5HZXQoNywgU1VCV0FZKQogICAgICAgICksCiAgICAgCiAgICAgICAgJ3ZhcycgICA9PiAgYXJyYXkoCiAgICAgICAgICAgICdzcG8nICAgPT4gIGNhbkdldCgxMCwgQlVTKSwKICAgICAgICAgICAgJ2dvcycgICA9PiAgY2FuR2V0KDcsIFNVQldBWSksCiAgICAgICAgICAgICdub3YnICAgPT4gIGNhbkdldCgxMSwgRk9PVCkKICAgICAgICApLAogICAgIAogICAgICAgICdrcmUnICAgPT4gIGFycmF5KAogICAgICAgICAgICAnZ29yJyAgID0+ICBjYW5HZXQoNSwgRk9PVCkKICAgICAgICApLAogICAgIAogICAgICAgICdsZXQnICAgPT4gIGFycmF5KAogICAgICAgICAgICAnZHZvJyAgID0+ICBjYW5HZXQoNiwgRk9PVCksCiAgICAgICAgICAgICdnb3MnICAgPT4gIGNhbkdldCg3LCBGT09UKQogICAgICAgICksCiAgICAgCiAgICAgICAgJ2R2bycgICA9PiAgYXJyYXkoCiAgICAgICAgICAgICdpc2EnICAgPT4gIGNhbkdldCg2LCBGT09UKSwKICAgICAgICAgICAgJ2dvcycgICA9PiAgY2FuR2V0KDYsIEZPT1QpLAogICAgICAgICAgICAnbGV0JyAgID0+ICBjYW5HZXQoNiwgRk9PVCkKICAgICAgICApLAogICAgIAogICAgICAgICdpc2EnICAgPT4gIGFycmF5KAogICAgICAgICAgICAnZHZvJyAgID0+ICBjYW5HZXQoNiwgRk9PVCksCiAgICAgICAgICAgICdub3YnICAgPT4gIGNhbkdldCg1LCBGT09UKQogICAgICAgICksCiAgICAgCiAgICAgICAgJ25vdicgICA9PiAgYXJyYXkoCiAgICAgICAgICAgICd2YXMnICAgPT4gIGNhbkdldCgxMSwgRk9PVCksCiAgICAgICAgICAgICdpc2EnICAgPT4gIGNhbkdldCg1LCBGT09UKSwKICAgICAgICAgICAgJ3JhcycgICA9PiAgY2FuR2V0KDcsIEJVUykKICAgICAgICApLAogICAgIAogICAgICAgICdyYXMnICAgPT4gIGFycmF5KAogICAgICAgICAgICAnbm92JyAgID0+ICBjYW5HZXQoNywgQlVTKSwKICAgICAgICAgICAgJ3NlbicgICA9PiAgY2FuR2V0KDMsIEZPT1QpCiAgICAgICAgKSwKICAgICAKICAgICAgICAnZ29zJyAgID0+ICBhcnJheSgKICAgICAgICAgICAgJ3ZhcycgICA9PiAgY2FuR2V0KDcsIFNVQldBWSksCiAgICAgICAgICAgICdzZW4nICAgPT4gIGNhbkdldCgzLCBTVUJXQVkpLAogICAgICAgICAgICAnZHZvJyAgID0+ICBjYW5HZXQoNiwgRk9PVCksCiAgICAgICAgICAgICdnb3InICAgPT4gIGNhbkdldCg2LCBTVUJXQVkpLAogICAgICAgICAgICAnbGV0JyAgID0+ICBjYW5HZXQoNywgRk9PVCksCiAgICAgICAgICAgICd2bGEnICAgPT4gIGNhbkdldCg3LCBGT09UKSAgICAgICAgCiAgICAgICAgKSwKICAgICAKICAgICAgICAnc2VuJyAgID0+ICBhcnJheSgKICAgICAgICAgICAgJ3JhcycgICA9PiAgY2FuR2V0KDMsIEZPT1QpLAogICAgICAgICAgICAnc3BvJyAgID0+ICBjYW5HZXQoNywgU1VCV0FZKSwKICAgICAgICAgICAgJ2dvcycgICA9PiAgY2FuR2V0KDMsIFNVQldBWSksCiAgICAgICAgICAgICd2bGEnICAgPT4gIGNhbkdldCg0LCBTVUJXQVkpLAogICAgICAgICAgICAndml0JyAgID0+ICBjYW5HZXQoMiwgU1VCV0FZKSwKICAgICAgICAgICAgJ3RlaCcgICA9PiAgY2FuR2V0KDMsIFNVQldBWSkKICAgICAgICApLAogICAgIAogICAgICAgICd2bGEnICAgPT4gIGFycmF5KAogICAgICAgICAgICAnc2VuJyAgID0+ICBjYW5HZXQoNCwgU1VCV0FZKSwKICAgICAgICAgICAgJ2dvcycgICA9PiAgY2FuR2V0KDcsIEZPT1QpLAogICAgICAgICAgICAndml0JyAgID0+ICBjYW5HZXQoMywgU1VCV0FZKQogICAgICAgICksCiAgICAgCiAgICAgICAgJ3ZpdCcgICA9PiAgYXJyYXkoCiAgICAgICAgICAgICdzZW4nICAgPT4gIGNhbkdldCgyLCBTVUJXQVkpLAogICAgICAgICAgICAndGVoJyAgID0+ICBjYW5HZXQoMiwgU1VCV0FZKSwKICAgICAgICAgICAgJ3ZsYScgICA9PiAgY2FuR2V0KDMsIFNVQldBWSkKICAgICAgICApLAogICAgIAogICAgICAgICd0ZWgnICAgPT4gIGFycmF5KAogICAgICAgICAgICAnc2VuJyAgID0+ICBjYW5HZXQoMywgU1VCV0FZKSwKICAgICAgICAgICAgJ3ZpdCcgICA9PiAgY2FuR2V0KDIsIFNVQldBWSkgICAgICAgIAogICAgICAgICkKICAgICk7CgogICAgZnVuY3Rpb24gY2FuR2V0KCR0aW1lLCAkYnlXaGF0KSAKICAgIHsKICAgICAgICByZXR1cm4gYXJyYXkoJ3RpbWUnICAgICA9PiAgJHRpbWUsICdieScgPT4gICRieVdoYXQpOwogICAgfQoKICAgIGZ1bmN0aW9uIGluaXRBbGdvcml0aG0oJHBhdGhzLCAkcG9pbnROYW1lcywgJHRyYW5zcG9ydE5hbWUsICRzdGFydFBvaW50LCAkZW5kUG9pbnQpCiAgICB7CiAgICAgICAgJHBhdGhzWyRzdGFydFBvaW50XVsnbGFiZWwnXSA9IDA7CiAgICAgICAgZm9yZWFjaCAoJHBhdGhzIGFzICRwb2ludCA9PiAmJHBvaW50VmFsdWUpIHsKICAgICAgICAgICAgaWYgKCRwb2ludCAhPSAkc3RhcnRQb2ludCkgewogICAgICAgICAgICAgICAgJHBvaW50VmFsdWVbJ2xhYmVsJ10gPSBQSFBfSU5UX01BWDsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcG9pbnRWYWx1ZVsndmlzaXRlZCddID0gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBkb0FsZ29yaXRobURlaWprc3RyYSgkcGF0aHMsICRwb2ludE5hbWVzLCAkdHJhbnNwb3J0TmFtZSwgJHN0YXJ0UG9pbnQsICRlbmRQb2ludCk7CiAgICB9CgogICAgZnVuY3Rpb24gcHJpbnRQYXRocygkcGF0aHMsICRwb2ludE5hbWVzLCAkdHJhbnNwb3J0TmFtZSwgJHRhcmdldFBhdGgsICRzdGFydFBvaW50LCAkZW5kUG9pbnQpCiAgICB7CiAgICAgICAgZWNobyAi0J3QsNGH0LDQu9GM0L3QsNGPINGC0L7Rh9C60LA6ICIgLiAkcG9pbnROYW1lc1skc3RhcnRQb2ludF0gLiAiXG4iOwogICAgICAgIGZvciAoJGkgPSAwOyAkaSA8IGNvdW50KCR0YXJnZXRQYXRoKSAtIDE7ICRpKyspIHsKICAgICAgICAgICAgJHRyYW5zcG9ydCA9ICR0cmFuc3BvcnROYW1lWyRwYXRoc1skdGFyZ2V0UGF0aFskaV1dWyR0YXJnZXRQYXRoWyRpICsgMV1dWydieSddXTsKICAgICAgICAgICAgZWNobyAi0JjQtyDQvdC10LUgeyR0cmFuc3BvcnR9INC00L4g0YLQvtGH0LrQuCAiIC4gJHBvaW50TmFtZXNbJHRhcmdldFBhdGhbJGkgKyAxXV0gLiAiICIgLiAkcGF0aHNbJHRhcmdldFBhdGhbJGldXVskdGFyZ2V0UGF0aFskaSsxXV1bJ3RpbWUnXSAuIiDQvNC40L3Rg9GCXG4iOwogICAgICAgIH0KICAgICAgICBlY2hvICLQkiDQuNGC0L7Qs9C1INGC0Ysg0L/QvtC/0LDQtNCw0LXRiNGMINCyINGC0L7Rh9C60YMgIiAuICRwb2ludE5hbWVzWyRlbmRQb2ludF0gLiAiINC30LAgIiAuICRwYXRoc1skZW5kUG9pbnRdWydsYWJlbCddIC4gIiDQvNC40L3Rg9GCLiDQn9GA0LjRj9GC0L3QvtC5INC/0L7QtdC30LTQutC4ISIgOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBzZWFyY2hQYXRoKCRwYXRocywgJHBvaW50TmFtZSwgJHRyYW5zcG9ydE5hbWUsICRzdGFydFBvaW50LCAkZW5kUG9pbnQpCiAgICB7CiAgICAgICAgJGN1cnJlbnRQb2ludCA9ICRlbmRQb2ludDsKICAgICAgICAkdGFyZ2V0UGF0aCA9IGFycmF5KCRjdXJyZW50UG9pbnQpOwogICAgICAgIAogICAgICAgIHdoaWxlICgkY3VycmVudFBvaW50ICE9ICRzdGFydFBvaW50KSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCRwYXRoc1skY3VycmVudFBvaW50XSBhcyAkcG9pbnQgPT4gJHBvaW50VmFsdWUpIHsKICAgICAgICAgICAgICAgIGlmICgkcG9pbnQgPT0gJ2xhYmVsJyB8fCAkcG9pbnQgPT0gJ3Zpc2l0ZWQnKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoJHBhdGhzWyRjdXJyZW50UG9pbnRdWydsYWJlbCddIC0gJHBhdGhzWyRjdXJyZW50UG9pbnRdWyRwb2ludF1bJ3RpbWUnXSA9PSAkcGF0aHNbJHBvaW50XVsnbGFiZWwnXSkgewogICAgICAgICAgICAgICAgICAgICR0YXJnZXRQYXRoW10gPSAkcG9pbnQ7CiAgICAgICAgICAgICAgICAgICAgJGN1cnJlbnRQb2ludCA9ICRwb2ludDsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHRhcmdldFBhdGggPSBhcnJheV9yZXZlcnNlKCR0YXJnZXRQYXRoKTsKCiAgICAgICAgcHJpbnRQYXRocygkcGF0aHMsICRwb2ludE5hbWUsICR0cmFuc3BvcnROYW1lLCAkdGFyZ2V0UGF0aCwgJHN0YXJ0UG9pbnQsICRlbmRQb2ludCk7CiAgICB9CgogICAgZnVuY3Rpb24gZG9BbGdvcml0aG1EZWlqa3N0cmEoJHBhdGhzLCAkcG9pbnROYW1lcywgJHRyYW5zcG9ydE5hbWUsICRzdGFydFBvaW50LCAkZW5kUG9pbnQpCiAgICB7CiAgICAgICAgJHBvaW50Q291bnQgPSBjb3VudCgkcGF0aHMpOwoKICAgICAgICBmb3IgKCRpID0gMDsgJGkgPCAkcG9pbnRDb3VudDsgJGkrKykgewogICAgICAgICAgICAkbWluTGFiZWwgPSBQSFBfSU5UX01BWDsKICAgICAgICAgICAgJHBvaW50TmFtZVdvcmsgPSBOVUxMOwoKICAgICAgICAgICAgZm9yZWFjaCAoJHBhdGhzIGFzICRwb2ludCA9PiAkcG9pbnRWYWx1ZSkgewogICAgICAgICAgICAgICAgaWYgKCRwb2ludFZhbHVlWydsYWJlbCddIDwgJG1pbkxhYmVsICYmICghJHBvaW50VmFsdWVbJ3Zpc2l0ZWQnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkbWluTGFiZWwgPSAkcG9pbnRWYWx1ZVsnbGFiZWwnXTsKICAgICAgICAgICAgICAgICAgICAkcG9pbnROYW1lV29yayA9ICRwb2ludDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJG5leHRQb2ludCA9ICRwYXRoc1skcG9pbnROYW1lV29ya107CgogICAgICAgICAgICBmb3JlYWNoICgkbmV4dFBvaW50IGFzICRwb2ludCA9PiAkcG9pbnRWYWx1ZSkgewogICAgICAgICAgICAgICAgaWYgKCEoYXJyYXlfa2V5X2V4aXN0cygkcG9pbnQsICRwb2ludE5hbWVzKSkpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRuZXdMYWJlbCA9ICRuZXh0UG9pbnRbJ2xhYmVsJ10gKyAkcGF0aHNbJHBvaW50TmFtZVdvcmtdWyRwb2ludF1bJ3RpbWUnXTsKICAgICAgICAgICAgICAgIGlmICgkcGF0aHNbJHBvaW50XVsnbGFiZWwnXSA+ICRuZXdMYWJlbCkgewogICAgICAgICAgICAgICAgICAgICRwYXRoc1skcG9pbnRdWydsYWJlbCddID0gJG5ld0xhYmVsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAkcGF0aHNbJHBvaW50TmFtZVdvcmtdWyd2aXNpdGVkJ10gPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgc2VhcmNoUGF0aCgkcGF0aHMsICRwb2ludE5hbWVzLCAkdHJhbnNwb3J0TmFtZSwgJHN0YXJ0UG9pbnQsICRlbmRQb2ludCk7CiAgICB9CgogICAgaW5pdEFsZ29yaXRobSgkcGF0aHMsICRwb2ludE5hbWVzLCAkdHJhbnNwb3J0TmFtZSwgJHN0YXJ0UG9pbnQsICRlbmRQb2ludCk7