Розв’яжіть транспортне перехрестя


26

Завдання

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

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

Вхід повинен мати таку форму:

  • Частина 1: чотири символи, кожен з яких має дорогу призначення для вихідних доріг у порядку N, E, S, W (за годинниковою стрілкою). Символи N, S, W, Eабо . Космос означає, що на конкретній дорозі немає транспортного засобу. Наприклад, рядок S WEозначає, що N транспортного засобу бажає їхати на південь, простір означає, що немає транспортного засобу E, Wозначає, що 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 випадків?
Charlie Wynn

Тож питання (і я припускаю рішення) припускає, що дорога, про яку йде мова, ведеться праворуч?
Терсосаврос

Саме так працює 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 (обидва рухи сумісні - паралельно-)
  • 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.