Pianifica una fermata a 4 vie


14

Un gruppo di macchine è allineato a un segnale di stop a 4 vie in attesa di procedere. Tutti sono confusi su chi deve andare dopo, chi sta andando in quale direzione, ecc. Chiaramente non ottimale.

Il tuo compito è pianificare il traffico allo stop in modo ottimale.

Ricevi come input 4 stringhe di richieste di svolta, una per ciascuna delle quattro direzioni cardinali. Ogni richiesta è Lper sinistra, Sper diritto o Rper destra.

LLSLRLS
SSSRRSRLLR
LLRLSR
RRRLLLL

La prima fila è la formazione all'ingresso nord dell'intersezione. La prima auto in linea desidera svoltare a sinistra (ovvero uscita est). Le righe successive sono per gli ingressi East, South e West in arrivo. Quindi la prima macchina proveniente da ovest desidera uscire a sud.

Il traffico si sposta in una serie di passaggi. Ad ogni passo, è necessario scegliere un sottoinsieme delle macchine in testa alle loro linee per procedere. Le auto scelte non devono interferire tra loro. Due auto interferiscono se escono nella stessa direzione o se devono incrociarsi reciprocamente (date le normali regole di guida a destra). Quindi due macchine opposte che desiderano entrambe andare dritte possono fare lo stesso passo. Quindi possono 4 macchine che desiderano girare a destra. Due macchine opposte possono entrambe girare contemporaneamente a sinistra.

Il tuo compito è pianificare l'intersezione in una serie minima di passaggi. Per ogni passaggio, emettere una linea con le direzioni della bussola delle auto in arrivo elencate. Per l'esempio sopra, la pianificazione minima è di 14 passaggi. Un programma minimo è:

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]

Il tuo programma dovrebbe essere in grado di gestire 50 auto in ogni linea in meno di 1 minuto. L'immissione delle 4 stringhe e l'output del programma possono essere in qualsiasi modo conveniente per la tua lingua.

Vince il programma più breve.

Un esempio più ampio:

RRLLSSRLSLLSSLRSLR
RLSLRLSLSSRLRLRRLLSSRLR
RLSLRLRRLSSLSLLRLSSL
LLLRRRSSRSLRSSSSLLRRRR

che richiede un minimo di 38 colpi. Una possibile soluzione:

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


Come hai calcolato il programma minimo per il primo esempio? Penso che questo sia un programma valido in 13 passaggi: NSW, NSW, ESW, EW, EW, NES, NE, EW, NE, NEW, NS, ES, E
ESultanik

@ESultanik: il tuo quarto passo, EW, ha l'Est che va dritto, l'Ovest che gira a sinistra. Questa non è una configurazione consentita.
Keith Randall,

@Fatalize: ho un programma che lo fa usando la programmazione dinamica.
Keith Randall,

Ah sì, mi dispiace per quello. Ho avuto un bug nel mio programma.
Invierò

Risposte:


3

Python, 1219 byte

Non ho speso molto tempo / sforzo nel cercare di giocare a golf, ma potrei migliorarlo se iniziassero a spuntare altre risposte. Uso una ricerca A * con un'euristica ammissibile , garantendo l'ottimalità. Sono abbastanza sicuro (anche se non mi sono preoccupato di confermare) che anche l'euristica sia coerente , nel senso che è O (programmazione dinamica).

Il programma legge in quattro righe da STDIN nel formato specificato e stampa il risultato su STDOUT, anche nel formato specificato.

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

Esempio di utilizzo:

$ 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.