Programar uma parada de 4 vias


14

Um monte de carros estão alinhados em um sinal de parada de 4 vias, esperando para prosseguir. Todo mundo está confuso sobre quem deve ir a seguir, quem está indo para o lado, etc. Claramente abaixo do ideal.

Seu trabalho é agendar o tráfego no sinal de parada da maneira ideal.

Você recebe como entrada 4 sequências de solicitações de turno, uma para cada uma das quatro direções principais. Cada solicitação é Lpara esquerda, Sreta ou Rdireita.

LLSLRLS
SSSRRSRLLR
LLRLSR
RRRLLLL

A primeira linha é a programação na entrada norte do cruzamento. O primeiro carro da fila deseja virar à esquerda (ou seja, sair para leste). As linhas subseqüentes são para as entradas Leste, Sul e Oeste de entrada. Assim, o primeiro carro vindo do oeste deseja sair do sul.

O tráfego se move em uma série de etapas. Em cada etapa, você deve escolher um subconjunto dos carros no início de suas linhas para continuar. Os carros escolhidos não devem interferir entre si. Dois carros interferem se eles saírem na mesma direção ou se precisarem atravessar o caminho um do outro (de acordo com as regras padrão de direção à direita). Portanto, dois carros opostos que desejam seguir em frente podem seguir o mesmo passo. O mesmo vale para 4 carros que desejam virar à direita. Dois carros opostos podem virar à esquerda simultaneamente.

Seu trabalho é agendar a interseção em uma série mínima de etapas. Para cada etapa, imprima uma linha com as direções da bússola dos carros recebidos listadas. Para o exemplo acima, o agendamento mínimo é de 14 etapas. Uma programação mínima é:

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]

Seu programa deve ser capaz de lidar com 50 carros em cada linha em menos de 1 minuto. A entrada das quatro strings e a saída da programação podem ser de qualquer maneira conveniente para o seu idioma.

O programa mais curto vence.

Um exemplo maior:

RRLLSSRLSLLSSLRSLR
RLSLRLSLSSRLRLRRLLSSRLR
RLSLRLRRLSSLSLLRLSSL
LLLRRRSSRSLRSSSSLLRRRR

o que requer um mínimo de 38 rodadas. Uma solução possível:

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


Como você calculou a programação mínima para o primeiro exemplo? Eu acho que este é um cronograma de 13 etapas válido: NSW, NSW, ESW, EW, EW, NES, NE, EW, NE, NOVO, NS, ES, E
ESultanik

@ESultanik: seu quarto passo, EW, tem o leste indo reto, o oeste virando à esquerda. Essa não é uma configuração permitida.
Keith Randall

@Fatalize: Eu tenho um programa que faz isso usando programação dinâmica.
Keith Randall

Ah sim, desculpe por isso. Eu tive um bug no meu programa. Em breve estarei postando uma resposta…
ESultanik 15/15/15

Respostas:


3

Python, 1219 bytes

Não gastei muito tempo / esforço tentando jogar isso, mas posso melhorar se outras respostas começarem a aparecer. Uso a pesquisa A * com uma heurística admissível , garantindo a otimização. Tenho certeza (embora não tenha me dado ao trabalho de confirmar) que a heurística também é consistente , o que significa que é O (programação dinâmica).

O programa lê em quatro linhas STDIN no formato que você especificou e imprime o resultado em STDOUT, também no formato que você especificou.

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

Exemplo de uso:

$ 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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.