Решить транспортную развязку


26

Задание

Напишите программу или функцию, которая принимает структуру перекрестка и выводит последовательность, в которой будут проезжать транспортные средства.

Выход должен содержать не более четырех строк следующего формата #. x->y\n, где #это номер порядковый номер, за которыми следует точка ., xи yэто символы ["N", "E", "S", "W"]. Они должны быть разделены символами ->. Если вы не возвращаете массив строк, каждая строка должна заканчиваться \n(символ новой строки) или эквивалентна вашей системе.

Ввод должен принимать следующую форму:

  • Часть 1: четыре символа, каждый из которых имеет дорогу назначения для исходных дорог в порядке N, E, S, W (по часовой стрелке). Допустимые символы N, S, W, Eили . Пространство означает, что на определенной дороге нет транспортного средства. Например, строка S WEозначает, что транспортное средство N желает ехать на юг, космическое означает, что нет транспортного Wсредства E, означает, что S желает ехать на запад, Eозначает, что запад желает ехать на восток.
  • Часть 2 - пробел или отдельная буква, означающая, какая из машин скорой помощи.
  • Часть 3 - два символа, определяющие, какие две дороги имеют приоритет (например, NEозначает, что север и восток имеют более высокий приоритет, чем юг и запад). Если вам легче, вы можете выбрать менее приоритетные дороги (в этом случае SW).

В неразрешимой ситуации вам разрешено возвращать однострочную строку, понятную пользователю, например unsolvable, no solutionи тому подобное. Пользователи JavaScript могут принимать встроенную undefinedконстанту.

Это код-гольф, поэтому выигрывает самый короткий ответ в байтах.

Правила дорожного движения

Обратите внимание, что некоторые правила могут не соответствовать правилам дорожного движения вашей страны. Некоторые из них были упрощены, чтобы облегчить задачу. Не используйте этот вопрос в качестве руководства для реальной системы дорожного движения.

  1. Для вызова вам разрешено использовать только правостороннее движение.
  2. Транспортная развязка состоит из ровно четырех дорог, которые встречаются в одной точке. Они помечены N(как «Север»), S, W, E. Эти буквы должны использоваться вместо xи yв приведенном выше примере вывода.

Пересечение

  1. На каждой дороге не более одного транспортного средства. Не гарантируется наличие транспортного средства на каждой дороге. Каждое транспортное средство может двигаться в любом из четырех направлений, т.е. поверните налево, поверните направо, идите прямо или сделайте разворот .

Возможные направления автомобиля S

  1. Если пути двух транспортных средств не пересекаются (они не сталкиваются), они могут идти в один и тот же момент. Пути не сталкиваются, если два транспортных средства (список может быть неполным, но это намеренно, просто чтобы дать вам подсказку):
    • идут с противоположных направлений, и оба идут прямо, или, по крайней мере, один из них поворачивает направо,
    • прийти с противоположных направлений, и оба повернуть налево,
    • исходить из противоположных направлений, и один из них поворачивает в любом направлении или делает разворот, в то время как другой делает разворот,
    • исходить из ортогональных направлений, один слева поворачивает направо, а другой не делает разворот

      Некоторые примеры не встречающихся путей ниже. Обратите внимание, что на третьем рисунке любой путь N будет сталкиваться с путем E, даже если N совершит разворот.

введите описание изображения здесь введите описание изображения здесь

введите описание изображения здесь введите описание изображения здесь

  1. Если два пути сталкиваются, необходимо использовать другие правила. Если два транспортных средства находятся на одной и той же приоритетной дороге (см. Ниже), транспортное средство получает право проезда, которое:
    • Это идет от дороги на правой стороне, если они идут с ортогональных направлений
    • поворачивает направо, если другой поворачивает налево
    • идет прямо или поворачивает направо, если другой делает разворот.

      В обоих приведенных ниже примерах транспортное средство E имеет право проезда над транспортным средством S.

введите описание изображения здесь введите описание изображения здесь

В приведенном ниже примере сначала идет W, затем N, затем E и последний идет S.

введите описание изображения здесь

Для этого конкретного случая вывод вашей программы должен быть:

1. W->S
2. N->S
3. E->S
4. S->S
  1. Все водители используют сигналы поворота и знают, куда все остальные хотят пойти (для простоты мы предполагаем, что можно различить левый поворот и разворот).

  2. Иногда дороги имеют приоритетные знаки, которые важнее, чем приведенные выше правила. Дорога с более высоким приоритетом имеет знак приоритета ( изображение знака приоритета ). Если приоритетная дорога не идет прямо, также используются дополнительные знаки, как этот . Дороги с более низким приоритетом имеют знак выхода или знак остановки (они эквивалентны). Ни одна, ни две разные дороги не будут иметь более высокого приоритета. Пользователь вашей программы должен иметь возможность указать, какие дороги имеют более высокий (или более низкий) приоритет.

  3. Транспортное средство, которое едет с дороги с более высоким приоритетом, имеет преимущество перед транспортным средством, движущимся с дороги с более низким приоритетом, даже если оно находится на левой стороне.
  4. Если сталкиваются пути двух транспортных средств, идущих с дорог с одинаковым приоритетом, действуют указанные выше правила правой стороны.

    На примере ниже дороги S и W имеют знаки приоритета, что означает, что транспортные средства на N и E должны указывать им путь. Автомобиль S имеет приоритет над автомобилем W, потому что он находится на правой стороне, поэтому идет первым. Затем идет W, потому что он находится на дороге с более высоким приоритетом, чем E. Транспортное средство N имеет право проезда от E, потому что оно находится на его правой стороне. По последнему выходит Э.

введите описание изображения здесь

Для этого конкретного случая вывод вашей программы должен быть:

1. S->W
2. W->N
3. N->S
4. E->W
  1. Вполне возможно, что одно (и не более) транспортное средство является транспортным средством скорой помощи , которое имеет приоритет независимо от того, в каком направлении оно идет или куда идет, и с каким знаком оно идет (оно всегда идет первым). Программа должна позволять пользователю вводить, какое транспортное средство является транспортным средством скорой помощи. Учитывая, что в последнем примере N является транспортным средством скорой помощи, N идет первым, затем S, W и как последний E.

Для этого конкретного случая с транспортным средством скорой помощи в N выходные данные вашей программы должны быть:

1. N->S
2. S->W
3. W->N
4. E->W
  1. Если двум транспортным средствам разрешено ехать в один и тот же момент (их пути не сталкиваются и они не должны уступать дорогу другим транспортным средствам), ваша программа должна это выяснить и вернуть их с одинаковым порядковым номером

    В приведенном ниже примере пути N и E, а также E и S или W и E не сталкиваются. Поскольку S должен уступить N, а W уступить S, S не может идти одновременно с E и т. Д. N и E могут. Так что сначала N и E идут вместе, затем идет S, а W как последний.

введите описание изображения здесь

Правильный вывод вашей программы должен быть:

1. N->W
1. E->E
2. S->W
3. W->N

Вы можете выбрать порядок строк 1( N->W / E->Eэквивалентно E->E / N->W)

  1. Иногда движение может привести к неразрешимой ситуации, которая не позволяет любому транспортному средству ехать. В реальной жизни это решается, когда один из водителей добровольно отказывается от своего права проезда. Здесь ваша программа должна выводить unsolvableи т. Д., Как указано в первой части вопроса.

    Ниже приведен пример неразрешимой ситуации. E должен уступить W, W должен уступить S, а S должен уступить E.

введите описание изображения здесь


3
Я думаю, что согласованный формат ввода должен быть определен. «У входа может быть любая структура, которая вам нравится» - это большой красный флаг. Может ли вход быть решением?
Увлечения Кэлвина

@ Calvin'sHobbies Я обновил вопрос
Voitcus

Есть ли шанс получить пример ввода / вывода для 1-2 случаев?
Чарли Винн

Таким образом, вопрос (и я предполагаю решение) предполагает, что рассматриваемая дорога (дороги) имеет правостороннее движение?
Терсосаврос

Именно так работают Google Cars
coredump,

Ответы:


8

Q, 645 байт

r:{(1_x),*x}                                                    /rot
R:{x 3,!3}                                                      /-rot
A:4 4#/:@[16#0;;:;]'[(&0100011001111100b;&0001111101100010b;&0010001111000100b;0);(&0 6 2;&0 1 7;&0 3 3;0)]
K:,/{,'/A x}'3 R\3 0 2 1                                        /Konflick matrix
G:3 R\|E:"NESW"                                                 /E:NESW  G:WSEN NWSE ENWS SENW    
m:{x-y*_x%y}                                                    /mod
t:{1=+/m'[_x%4;2]}                                              /orthogonal
w:{-1($x),". ",y[0],"->",y 1;}                               /write
b:{_x%4}                                                        /n-> base dir.
g:m[;4]                                                         /n-> turn
e:(!4)in                                                        /exists
d:{s:r a:e b x;R s&~a}                                       /right free
I:{(G[a]?x 1)+4*a:E?*x}                                         /"dd"->n
O:{E[a],G[a:b x]g x}                                            /n-> "dd"
P:{N::(y=4)&z~4 4;a@&0<a:(@[4#0;b x;:;4-g x])+(5*d x)+(24*e z)+99*e y}          /priority
H:{a::K ./:/:x,/:\:x; if[N&2 in *a;:,0N]; x@&{~|/x[;z]'y}[a]'[!:'u+1;u:!#x]}    /each set of concurrent movements
f:{i:I'(E,'a)@&~^a:4#x; i:i@p:>P[i;E?x 4;E?x 5 6]; {0<#x 1}{a:H x 1;$[a~,0N;-1"unsolvable";w[*x]'O'a];$[a~,0N;(0;());(1+*x;x[1]@&~x[1] in a)]}/(1;i);}

КОММЕНТАРИИ

Определенно, это не короткий (и не простой) код. Это может быть (сильно) сжато, но это оставлено как упражнение для читателя (я посвятил слишком много времени этой проблеме).

Я включил многострочное закомментированное решение, но предполагаю, что новые строки равны 1 байту и отбрасывают комментарии (от / до конца строки) для подсчета размера

Основная сложность заключается в том, чтобы полностью понять все правила. Ранняя оптимизация длины кода несовместима с разработкой решения сложной проблемы. Ни восходящий, ни нисходящий подход не справляются с нечитаемым кодом.

Наконец, я разработал таблицу решений (матрицу конфликтов) с 16 строками и 16 столбцами (для каждого направления в сочетании с каждым возможным поворотом). Значения элементов: 0 (совместимость), 1 (предпочтение для строки) или 2 (предпочтение для столбца). Он удовлетворяет всем требованиям, я не уверен, что все возможные ситуации хорошо освещены.

Исходный файл должен иметь расширение k. Запустите интерактивный переводчик (бесплатно для некоммерческого использования, kx.com) и оцените его сразу же (как показано в пункте «Тест»)

ТЕСТ

q)f " WN    "
1. E->W
2. S->N

q)f " SW    "
1. E->S
2. S->W

q)f "SSSS   "
1. W->S
2. N->S
3. E->S
4. S->S

q)f "SWWN WS"
1. S->W
2. W->N
3. N->S
4. E->W

q)f "SWWNNWS"
1. N->S
2. S->W
3. W->N
4. E->W

q)f "WEWN   "
1. N->W
1. E->E
2. S->W
3. W->N

q)f " SWE   "
unsolvable

ОБЪЯСНЕНИЕ

Базовая структура - это «матрица предшествования»

   N       E       S       W   
   W S E N N W S E E N W S S E N W
NW 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1
 S 0 0 0 0 0 1 1 0 0 0 1 1 2 2 2 2
 E 0 0 0 0 0 1 1 1 2 2 0 0 0 2 2 0
 N 0 0 0 0 2 2 0 0 0 2 0 0 0 0 2 0
EN 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0
 W 2 2 2 2 0 0 0 0 0 1 1 0 0 0 1 1
 S 0 2 2 0 0 0 0 0 0 1 1 1 2 2 0 0
 E 0 0 2 0 0 0 0 0 2 2 0 0 0 2 0 0
SE 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0
 N 0 0 1 1 2 2 2 2 0 0 0 0 0 1 1 0
 W 2 2 0 0 0 2 2 0 0 0 0 0 0 1 1 1
 S 0 2 0 0 0 0 2 0 0 0 0 0 2 2 0 0
WS 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0
 E 0 1 1 0 0 0 1 1 2 2 2 2 0 0 0 0
 N 0 1 1 1 2 2 0 0 0 2 2 0 0 0 0 0
 W 2 2 0 0 0 2 0 0 0 0 2 0 0 0 0 0

Значение (на примере)

  • m[NW][SE] имеет значение 0 (оба движения совместимы -concurrent-)
  • m[EW][SN] имеет значение 1 (EW имеет приоритет над SN) ПРИМЕЧАНИЕ. Другие факторы приоритета могут изменить это предложение (машины скорой помощи, приоритетная дорога, ..)
  • m[NE][SE] имеет значение 2 (SE имеет приоритет над NE). ПРИМЕЧАНИЕ. Другие факторы приоритета могут изменить это предложение (машины скорой помощи, приоритетная дорога, ..)

Матрица может быть построена с использованием четырех подматриц (4х4) типов

  NESW  A    B    C    D
N DACB  0100 0001 0010 0000
E BDAC  0110 2222 0011 0000
S CBDA  0111 0220 2200 0000
W ACBD  2200 0020 0200 0000

Матрица дополняется функцией, которая назначает приоритет каждому движению. Эта функция учитывает машины скорой помощи, приоритетные дороги, ортогональные направления, тип поворота и транспортные средства, движущиеся справа.

Мы сортируем движения по приоритету и применяем матричные значения. Результирующая подматрица включает конфликты и приоритет каждого движения.

  • анализируем неразрешимые случаи (взаимные конфликты)
  • если нет, мы выбираем наиболее приоритетный элемент и все движения, совместимые с ним и не несовместимые с предыдущими несовместимыми движениями, и создаем набор движений, которые могут выполняться одновременно
  • Напишите этот набор движений и переберите остальных кандидатов
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.