Заплануйте чотиристоронній зупинку


14

Купа машин вишикується у 4-х сторонній знак зупинки в очікуванні продовження. Усі плутаються щодо того, хто рухається далі, хто прямує і т. Д. Явно неоптимальний.

Ваше завдання полягає в оптимальному плануванні руху руху на знаку зупинки.

Ви отримуєте в якості 4 рядків запитів повороту, по одному для кожного з чотирьох кардинальних напрямків. Кожен запит - або Lдля лівої, Sдля прямої, або Rдля правої.

LLSLRLS
SSSRRSRLLR
LLRLSR
RRRLLLL

Перший ряд - це смуга біля входу на північ до перехрестя. Перший автомобіль в черзі хоче повернути ліворуч (тобто вийти на Схід). Наступні ряди призначені для входу на Схід, Південь та Захід. Тож перший автомобіль, що приїжджає із Заходу, бажає вийти на Південь.

Трафік рухається послідовно. На кожному кроці ви повинні вибрати підмножину автомобілів на чолі їх ліній, щоб продовжити. Вибрані машини не повинні перешкоджати один одному. Два автомобілі заважають, якщо вони виходять з одного напрямку або якщо вони повинні перетинати шлях один одного (з урахуванням стандартних правильних правил водіння). Тож два протилежні автомобілі, які бажають їхати прямо, можуть піти на одному кроці. Так можуть 4 машини, всі бажаючі повернути праворуч. Дві протилежні машини можуть одночасно повернути ліворуч.

Ваше завдання полягає в плануванні перехрестя в мінімальній серії кроків. Для кожного кроку виведіть рядок із вказаними напрямками компасів вхідних автомобілів. Для наведеного вище прикладу мінімальний графік - 14 кроків. Один мінімальний графік:

N    [L from North]
E    [S from East]
E    [S from East]
E    [S from East]
NESW [L from North, R from East, L from South, R from West]
NE   [S from North]
EW   [R from East]
NESW [L from North, R from East, L from South, R from West]
W    [L from West]
EW   [L from East, L from West]
NESW [R from North, L from East, R from South, L from West]
NES  [L from North, R from East, L from West]
NS   [S from North, S from South]
SW   [R from South, L from West]

Ваша програма повинна мати можливість обробляти 50 машин у кожній лінії за 1 хвилину. Введення 4-х рядків та вихід розкладу може бути зручним для вашої мови.

Найкоротша програма виграє.

Більш великий приклад:

RRLLSSRLSLLSSLRSLR
RLSLRLSLSSRLRLRRLLSSRLR
RLSLRLRRLSSLSLLRLSSL
LLLRRRSSRSLRSSSSLLRRRR

що вимагає мінімум 38 патронів. Одне можливе рішення:

E
EW
E
ESW
S
NS
ES
NESW
NSW
ESW
ES
NSW
NS
NS
NW
EW
NSW
NS
EW
NES
EW
NSW
NE
E
NE
EW
E
E
EW
EW
EW
W
ESW
NSW
NSW
NS
NSW
NEW


Як ви обчислили мінімальний графік для першого прикладу? Я думаю, що це дійсний 13-ступінковий графік: NSW, NSW, ESW, EW, EW, NES, NE, EW, NE, NEW, NS, ES, E
ESultanik

@ESultanik: на вашому четвертому кроці, EW, Схід йде прямо, Захід повертає ліворуч. Це не дозволена конфігурація.
Кіт Рендалл

@Fatalize: У мене є програма, яка робить це за допомогою динамічного програмування.
Кіт Рендалл

Ага так, вибачте за це. У мене була помилка в моїй програмі. Я скоро опублікую відповідь…
ESultanik

Відповіді:


3

Пітон, 1219 байт

Я не витрачав дуже багато часу / зусиль на те, щоб пограти в гольф, але я міг би покращити це, якщо з’являться інші відповіді. Я використовую пошук A * з допустимим евристичним , гарантуючи оптимальність. Я майже впевнений (хоча я не намагався підтвердити), що евристика також є послідовною , це означає, що це O (динамічне програмування).

Програма читає у чотирьох рядках зі STDIN у визначеному вами форматі та друкує результат у STDOUT, також у вказаному вами форматі.

from heapq import heappush,heappop
from itertools import combinations
N,E,S,W=range(4)
L="L"
R="R"
T="S"
d=[{L:E,R:W,T:S},{L:S,R:N,T:W},{L:W,R:E,T:N},{L:N,R:S,T:E}]
b=set([(N,S,W,E),(N,S,E,W),(S,N,W,E),(S,N,E,W),(E,W,N,E),(N,S,W,N),(S,N,E,S),(W,E,S,W)])
for x in list(b):b.add(x[2:]+x[:2])
def v(*a):return a[1]!=a[3] and a not in b
i=lambda:raw_input()+'\n'
i=map(lambda l:map(lambda e:("NESW"[l[0]],d[l[0]][e]), l[1]),enumerate((i()+i()+i()+i()).split()))
q=[]
heappush(q,(0,[],i))
while q:
    h,a,n=heappop(q)
    m=sum(map(bool,n))
    if m==0:
        print "\n".join(a)
        break
    for r in range(4,0,-1):
        f=False
        for c in combinations(range(4),r):
            l=True
            for i in c:
                if not n[i]:
                    l=False
                    break
            if not l:continue
            l=True
            for x,y in combinations(c,2):
                if not v(x,n[x][0][1],y,n[y][0][1]):
                    l = False
                    break
            if l==False:continue
            f=True
            e=list(n)
            for i in c:e[i]=e[i][1:]
            heappush(q,(m-r+min(map(len,e)),a+["".join([n[x][0][0] for x in c])],e))
        if f:break

Приклад використання:

$ time echo "RRLLSSRLSLLSSLRSLR\nRLSLRLSLSSRLRLRRLLSSRLR\nRLSLRLRRLSSLSLLRLSSL\nLLLRRRSSRSLRSSSSLLRRRR" | python 4way.py
NES
NEW
NSW
NS
NS
ESW
NS
NES
NEW
NS
NES
NSW
NS
NS
NSW
NW
NS
NS
NS
EW
ES
SW
EW
EW
SW
ES
EW
EW
EW
EW
E
EW
EW
EW
EW
EW
E
EW
echo   0.00s user 0.00s system 38% cpu 0.002 total
python 4way.py  0.02s user 0.01s system 90% cpu 0.030 total
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.