fork download
  1. <?php
  2.  
  3.  
  4. define('SUBWAY', 'sub');
  5. define('FOOT', 'foot');
  6. define('BUS', 'bus');
  7.  
  8. $transportName = array(
  9. SUBWAY => 'едешь на метро',
  10. FOOT => 'идешь пешком',
  11. BUS => 'едешь на автобусе'
  12. );
  13.  
  14. $startPoint = 'pet'; // Петроградская
  15. $endPoint = 'nov'; // Новая Голландия
  16.  
  17. $pointNames = array(
  18. 'pet' => 'ст. м. Петроградская',
  19. 'chk' => 'ст. м. Чкаловская',
  20. 'gor' => 'ст. м. Горьковская',
  21. 'spo' => 'ст. м. Спортивная',
  22. 'vas' => 'ст. м. Василеостровская',
  23. 'kre' => 'Петропавловская крепость',
  24. 'let' => 'Летний сад',
  25. 'dvo' => 'Дворцовая площадь',
  26. 'isa' => 'Исакиевский собор',
  27. 'nov' => 'Новая Голландия',
  28. 'ras' => 'Дом Раскольникова',
  29. 'gos' => 'Гостиный Двор',
  30. 'sen' => 'Сенная Площадь',
  31. 'vla' => 'ст. м. Владимирская',
  32. 'vit' => 'Витебский вокзал',
  33. 'teh' => 'Технологический Институт'
  34. );
  35.  
  36. $paths = array(
  37. 'pet' => array(
  38. 'chk' => canGet(10, BUS),
  39. 'gor' => canGet(3, SUBWAY)
  40. ),
  41.  
  42. 'chk' => array(
  43. 'pet' => canGet(10, BUS),
  44. 'spo' => canGet(3, SUBWAY)
  45. ),
  46.  
  47. 'gor' => array(
  48. 'pet' => canGet(3, BUS),
  49. 'kre' => canGet(5, FOOT),
  50. 'gos' => canGet(6, SUBWAY)
  51. ),
  52.  
  53. 'spo' => array(
  54. 'chk' => canGet(3, SUBWAY),
  55. 'vas' => canGet(10, BUS),
  56. 'sen' => canGet(7, SUBWAY)
  57. ),
  58.  
  59. 'vas' => array(
  60. 'spo' => canGet(10, BUS),
  61. 'gos' => canGet(7, SUBWAY),
  62. 'nov' => canGet(11, FOOT)
  63. ),
  64.  
  65. 'kre' => array(
  66. 'gor' => canGet(5, FOOT)
  67. ),
  68.  
  69. 'let' => array(
  70. 'dvo' => canGet(6, FOOT),
  71. 'gos' => canGet(7, FOOT)
  72. ),
  73.  
  74. 'dvo' => array(
  75. 'isa' => canGet(6, FOOT),
  76. 'gos' => canGet(6, FOOT),
  77. 'let' => canGet(6, FOOT)
  78. ),
  79.  
  80. 'isa' => array(
  81. 'dvo' => canGet(6, FOOT),
  82. 'nov' => canGet(5, FOOT)
  83. ),
  84.  
  85. 'nov' => array(
  86. 'vas' => canGet(11, FOOT),
  87. 'isa' => canGet(5, FOOT),
  88. 'ras' => canGet(7, BUS)
  89. ),
  90.  
  91. 'ras' => array(
  92. 'nov' => canGet(7, BUS),
  93. 'sen' => canGet(3, FOOT)
  94. ),
  95.  
  96. 'gos' => array(
  97. 'vas' => canGet(7, SUBWAY),
  98. 'sen' => canGet(3, SUBWAY),
  99. 'dvo' => canGet(6, FOOT),
  100. 'gor' => canGet(6, SUBWAY),
  101. 'let' => canGet(7, FOOT),
  102. 'vla' => canGet(7, FOOT)
  103. ),
  104.  
  105. 'sen' => array(
  106. 'ras' => canGet(3, FOOT),
  107. 'spo' => canGet(7, SUBWAY),
  108. 'gos' => canGet(3, SUBWAY),
  109. 'vla' => canGet(4, SUBWAY),
  110. 'vit' => canGet(2, SUBWAY),
  111. 'teh' => canGet(3, SUBWAY)
  112. ),
  113.  
  114. 'vla' => array(
  115. 'sen' => canGet(4, SUBWAY),
  116. 'gos' => canGet(7, FOOT),
  117. 'vit' => canGet(3, SUBWAY)
  118. ),
  119.  
  120. 'vit' => array(
  121. 'sen' => canGet(2, SUBWAY),
  122. 'teh' => canGet(2, SUBWAY),
  123. 'vla' => canGet(3, SUBWAY)
  124. ),
  125.  
  126. 'teh' => array(
  127. 'sen' => canGet(3, SUBWAY),
  128. 'vit' => canGet(2, SUBWAY)
  129. ),
  130. 'isa' => array(
  131. 'dvo' => canGet(6, FOOT),
  132. 'nov' => canGet(5, FOOT)
  133. ),
  134.  
  135. );
  136.  
  137. /* Чтобы не писать много раз array('time' => ..., 'by' => ...), используем функцию.
  138.   «canGet» переводится как «можно попасть» */
  139. function canGet($time, $byWhat)
  140. {
  141. return array('time' => $time, 'by' => $byWhat);
  142. }
  143.  
  144. function makeOneMoreStep($paths, $pathDone, $time, $point, $target, $theNumbOf)
  145. {
  146. $waysAndTimes[] = ['path' => null, 'time' => INF];
  147. if (array_key_exists($target, $paths[$point])) {
  148. $time += $paths[$point][$target]['time'];
  149. $pathDone[] = $target;
  150. $theNumbOf += 1;
  151. $waysAndTimes[] = ['path' => $pathDone, 'time' => $time];
  152. }
  153. foreach ($paths[$point] as $subTarget => $timeAndBy) {
  154. if (!in_array($subTarget, $pathDone) and !in_array($subTarget, $pathDone)) {
  155. list('path and time' => $waysAndTimes[], 'possible ways' => $theNumbOf) = makeOneMoreStep($paths, array_merge($pathDone, [$subTarget]), $time + $paths[$point][$subTarget]['time'], $subTarget, $target, $theNumbOf);
  156.  
  157. }
  158. }
  159. return ['path and time' => bestPath($waysAndTimes), 'possible ways' => $theNumbOf];
  160. }
  161.  
  162. function bestPath($waysAndTimes)
  163. {
  164. $bestTime = INF;
  165. $bestPath = 0;
  166. foreach ($waysAndTimes as $pathNumber => $wayAndTime) {
  167. if ($wayAndTime['time'] < $bestTime) {
  168. $bestTime = $wayAndTime['time'];
  169. $bestPath = $pathNumber;
  170. }
  171. }
  172. return $waysAndTimes[$bestPath];
  173. }
  174.  
  175. $point = 'pet'; // Старт
  176. $target = 'nov'; // Финиш
  177. $pathDone = [$point];
  178. $time = 0;
  179.  
  180. print_r(makeOneMoreStep($paths, $pathDone, $time, $point, $target, 0));
  181. $pathAndTimePossibleWays = makeOneMoreStep($paths, $pathDone, $time, $point, $target, 0);
  182.  
  183. $bestPath = $pathAndTimePossibleWays['path and time']['path'];
  184. $bestTime = $pathAndTimePossibleWays['path and time']['time'];
  185.  
  186. echo "Начальная точка: $pointNames[$point]" . PHP_EOL;
  187. for ($i = 0; $i < count($bestPath) - 1; $i++) {
  188. $a = $bestPath[$i];
  189. $b = $bestPath[$i + 1];
  190. echo "Из нее {$transportName[$paths[$a][$b]['by']]} до точки {$pointNames[$bestPath[$i+1]]} {$paths[$a][$b]['time']} мин" . PHP_EOL;
  191. }
  192. echo "В итоге ты попадешь в точку {$pointNames[$b]} за {$bestTime} минут ";
Success #stdin #stdout 0.02s 24160KB
stdin
Standard input is empty
stdout
Array
(
    [path and time] => Array
        (
            [path] => Array
                (
                    [0] => pet
                    [1] => gor
                    [2] => gos
                    [3] => sen
                    [4] => ras
                    [5] => nov
                )

            [time] => 22
        )

    [possible ways] => 32
)
Начальная точка: ст. м. Петроградская
Из нее едешь на метро до точки ст. м. Горьковская 3 мин
Из нее едешь на метро до точки Гостиный Двор 6 мин
Из нее едешь на метро до точки Сенная Площадь 3 мин
Из нее идешь пешком до точки Дом Раскольникова 3 мин
Из нее едешь на автобусе до точки Новая Голландия 7 мин
В итоге ты попадешь в точку Новая Голландия за 22 минут