Расписание остановки в 4 направлениях


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: у вашего 4-го шага, EW, Восток идет прямо, Запад поворачивает налево. Это недопустимая конфигурация.
Кит Рэндалл

@Fatalize: у меня есть программа, которая делает это с помощью динамического программирования.
Кит Рэндалл

Ах да, извините за это. У меня была ошибка в моей программе. Я скоро
выложу

Ответы:


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.