<?php

error_reporting(-1);
/* http://d...content-available-to-author-only...2.net/ */

define('SUBWAY', 'sub');
define('FOOT', 'foot');
define('BUS', 'bus');

$transportName = array(
    SUBWAY => 'едешь на метро',
    FOOT => 'идешь пешком',
    BUS => 'едешь на автобусе'
);

$startPoint = 'pet'; // Петроградская
$endPoint = 'nov'; // Новая Голландия

$pointNames = array(
    'pet' => 'ст. м. Петроградская',
    'chk' => 'ст. м. Чкаловская',
    'gor' => 'ст. м. Горьковская',
    'spo' => 'ст. м. Спортивная',
    'vas' => 'ст. м. Василеостровская',
    'kre' => 'Петропавловская крепость',
    'let' => 'Летний сад',
    'dvo' => 'Дворцовая площадь',
    'isa' => 'Исакиевский собор',
    'nov' => 'Новая Голландия',
    'ras' => 'Дом Раскольникова',
    'gos' => 'Гостиный Двор',
    'sen' => 'Сенная Площадь',
    'vla' => 'ст. м. Владимирская',
    'vit' => 'Витебский вокзал',
    'teh' => 'Технологический Институт'
);

$paths = array(
    'pet' => array(
        'chk' => canGet(10, BUS),
        'gor' => canGet(3, SUBWAY)
    ),

    'chk' => array(
        'pet' => canGet(10, BUS),
        'spo' => canGet(3, SUBWAY)
    ),

    'gor' => array(
        'pet' => canGet(3, BUS),
        'kre' => canGet(5, FOOT),
        'gos' => canGet(6, SUBWAY)
    ),

    'spo' => array(
        'chk' => canGet(3, SUBWAY),
        'vas' => canGet(10, BUS),
        'sen' => canGet(7, SUBWAY)
    ),

    'vas' => array(
        'spo' => canGet(10, BUS),
        'gos' => canGet(7, SUBWAY),
        'nov' => canGet(11, FOOT)
    ),

    'kre' => array(
        'gor' => canGet(5, FOOT)
    ),

    'let' => array(
        'dvo' => canGet(6, FOOT),
        'gos' => canGet(7, FOOT)
    ),

    'dvo' => array(
        'isa' => canGet(6, FOOT),
        'gos' => canGet(6, FOOT),
        'let' => canGet(6, FOOT)
    ),

    'isa' => array(
        'dvo' => canGet(6, FOOT),
        'nov' => canGet(5, FOOT)
    ),

    'nov' => array(
        'vas' => canGet(11, FOOT),
        'isa' => canGet(5, FOOT),
        'ras' => canGet(7, BUS)
    ),

    'ras' => array(
        'nov' => canGet(7, BUS),
        'sen' => canGet(3, FOOT)
    ),

    'gos' => array(
        'vas' => canGet(7, SUBWAY),
        'sen' => canGet(3, SUBWAY),
        'dvo' => canGet(6, FOOT),
        'gor' => canGet(6, SUBWAY),
        'let' => canGet(7, FOOT),
        'vla' => canGet(7, FOOT)
    ),

    'sen' => array(
        'ras' => canGet(3, FOOT),
        'spo' => canGet(7, SUBWAY),
        'gos' => canGet(3, SUBWAY),
        'vla' => canGet(4, SUBWAY),
        'vit' => canGet(2, SUBWAY),
        'teh' => canGet(3, SUBWAY)
    ),

    'vla' => array(
        'sen' => canGet(4, SUBWAY),
        'gos' => canGet(7, FOOT),
        'vit' => canGet(3, SUBWAY)
    ),

    'vit' => array(
        'sen' => canGet(2, SUBWAY),
        'teh' => canGet(2, SUBWAY),
        'vla' => canGet(3, SUBWAY)
    ),

    'teh' => array(
        'sen' => canGet(3, SUBWAY),
        'vit' => canGet(2, SUBWAY)
    )
);

/* Чтобы не писать много раз array('time' => ..., 'by' => ...), используем функцию.
  «canGet» переводится как «можно попасть» */
function canGet($time, $byWhat) {
    return array('time' => $time, 'by' => $byWhat);
}

function makeOneStep($paths, $pathDone, $time, $point, $target){
    $pathDone[] = $point;                                                       // Заносим в пройденный путь точку в которой находимся
    if($point == $target){                                                      // Если находимся в точке назначения
        $result["path"] = $pathDone;                                            // Записываем пройденный путь в массив
        $result["time"] = $time;                                                // Записываем время в массив
        return $result;                                                         // Возврщаем массив с пройденныи путем и временем
    }

    $result = array();                                                          // Массив в которой заносим маршрут и время
    foreach ($paths[$point] as $node => $pathTimeBy) {                          // Цикл для перебора всех возможных маршрутов
        if(!in_array($node,$pathDone)){                                         // Если точка не находится в пройденном пути
            $time = $time + $pathTimeBy["time"];                                // Обновляем время. Идем вперед плюсуем время
            $newPath = makeOneStep($paths,$pathDone,$time,$node,$target);       // Вызываем функцию с обновленными параметрами точки прибывания и времени.
            if($newPath){                                                       // Если в $newPath есть маршрут
                if(!$result || ($newPath["time"] < $result["time"])){           // Если массив $result пуст или если новый маршрут меньше предыдущего
                    $result["path"] = $newPath["path"];                         // Записываем новый маршрут
                    $result["time"] = $newPath["time"];                         // Записываем новое время
                }
            }
            $time = $time - $pathTimeBy["time"];                                // Обновляем время. Идем обратно минусуем время
        }
    }

    return $result;                                                             // Возвращаем маршрут
}


$pathDone = array(); // Пройденый путь
$time = 0;           // Затраченное время

$path = makeOneStep($paths, $pathDone, $time, $startPoint, $endPoint);                   // Вызываем функцию
$nodes =$path["path"];                                                                   // Массив с маршрутом

echo "Начальная точка: \"$pointNames[$startPoint]\"\n";                                  // Выводим начальную точку
for($i = 0; $i < count($nodes)-1; $i++){                                                 // Цикл для маршрута
    $from = $nodes[$i];                                                                  // Откуда
    $to = $nodes[$i+1];                                                                  // Куда
    $howMuch =$paths[$from][$to]["time"];                                                // Сколько займет времени
    $how = $paths[$from][$to]["by"];                                                     // Как будем добиратся
    echo "Из неё $transportName[$how] до точки \"$pointNames[$to]\" $howMuch мин.\n";    // Выводим поэтапно маршрут
}
echo "В итоге ты попадаешь в точку \"$pointNames[$endPoint]\" за ".$path["time"]." мин. Приятной поездки!"; // Выводим конечную точку назанчения и общее время затраченное в пути