<?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 oneStep($paths, $point, $target)
{
    $inf       = 100000;
    $time      = array();
    $visited   = array();
    $visited[] = $point;
    $pathDone  = array();
    foreach ($paths as $key => $value) {
        asort($paths[$key]);
        $time[$key] = $inf;
    }
    $time[$point] = 0;
    foreach ($paths[$point] as $key => $val) {
        $time[$key]     = $paths[$point][$key]['time'];
        $pathDone[$key] = array(
            $key
        );
        
    }
    
    while(count($visited)<count($paths)){
        foreach ($paths as $key => $val) {
            if ($time[$key] == $inf || (in_array($key, $visited))) {
                continue;
            }
            foreach ($paths[$key] as $subkey => $val) {
                if ($time[$subkey] > $time[$key] + $paths[$key][$subkey]['time']) {
                    $time[$subkey]       = $time[$key] + $paths[$key][$subkey]['time'];
                    $pathDone[$subkey]   = $pathDone[$key];
                    $pathDone[$subkey][] = $subkey;
                }
            }
            $visited[] = $paths[$key];
            
        }
        
    }
    $result         = array();
    $result['time'] = $time[$target];
    $result['path'] = $pathDone[$target];
    return $result;
    
}




function showPath($paths, $point, $target, $pointNames, $transportName)
{
    $result   = oneStep($paths, $point, $target);
    $previous = $point;
    echo "Начальная точка: $pointNames[$point]\n";
    foreach ($result['path'] as $key => $value) {
        $translate = $paths[$previous][$value]['by'];
        echo "Из неё $transportName[$translate] в точку $pointNames[$value] {$paths[$previous][$value]['time']} мин\n";
        $previous = $value;
    }
    echo "В итоге ты попадешь в точку $pointNames[$target] за ";
    echo $result['time'];
    echo "минут";
}
showPath($paths, $startPoint, $endPoint, $pointNames, $transportName);