Risolve un incrocio di traffico


26

L'obiettivo

Scrivi un programma o una funzione che prende una struttura di intersezione del traffico e genera la sequenza in cui passeranno i veicoli.

L'output dovrebbe contenere al massimo quattro linee con il seguente formato #. x->y\n, dove #è un numero di sequenza, seguiti dal puntino ., xe ysono caratteri ["N", "E", "S", "W"]. Dovrebbero essere separati da caratteri ->. Se non si restituisce una matrice di stringhe, ogni riga deve terminare con un \n(nuovo carattere di riga) o equivalente al proprio sistema.

L'input dovrebbe assumere la forma seguente:

  • Parte 1: quattro personaggi, ognuno con la strada di destinazione per le strade di origine nell'ordine N, E, S, W (in senso orario). I caratteri consentiti sono N, S, W, Eo . Lo spazio significa che non esiste alcun veicolo su una determinata strada. Ad esempio, stringa S WEsignifica che N veicolo vuole andare a sud, lo spazio significa che non c'è veicolo E, Wche S vuole andare ad ovest, Esignifica che Ovest vuole andare ad est.
  • Parte 2 - uno spazio o una singola lettera che significa quale è del veicolo di emergenza.
  • Parte 3: due caratteri che determinano quali due strade hanno la priorità (ad es. NESignifica che Nord e Est hanno entrambe priorità più alte rispetto a Sud e Ovest). Se è più facile per te, potresti prendere strade con priorità più bassa (in quel caso SW).

In una situazione irrisolvibile si è permesso di restituire una stringa di una riga che è chiaro per l'utente, come unsolvable, no solutione simili. Gli utenti JavaScript possono prendere la undefinedcostante integrata .

Questo è un codice-golf, quindi vince la risposta più breve in byte.

Le regole del traffico

Si noti che alcune delle regole potrebbero non seguire le regole del proprio Paese. Alcuni di essi sono stati semplificati per facilitare la sfida. Non utilizzare questa domanda come guida per il sistema di traffico reale.

  1. Per la sfida è consentito utilizzare solo il traffico sul lato destro.
  2. L'intersezione del traffico è costituita da esattamente quattro strade che si incontrano in un punto. Essi sono contrassegnati N(come per "Nord"), S, W, E. Queste lettere dovrebbero essere usate al posto xe ynell'esempio di output sopra.

Un incrocio

  1. Su ogni strada c'è al massimo un veicolo. Non è garantito che ci sia un veicolo su ogni strada. Ogni veicolo può guidare in una delle quattro direzioni, ad es. girare a sinistra, svoltare a destra, proseguire dritto o fare un inversione di marcia .

Possibili destinazioni del veicolo S.

  1. Se i percorsi di due veicoli non si intersecano (non si scontrano), possono andare nello stesso momento. I percorsi non si scontrano, se due veicoli (l'elenco potrebbe non essere completo, ma questo è intenzionale, solo per darti un indizio):
    • provengono da direzioni opposte ed entrambi vanno dritti, o almeno uno di essi gira a destra,
    • provengono da direzioni opposte ed entrambi girano a sinistra,
    • provengono da direzioni opposte e una di esse gira in qualsiasi direzione o fa l'inversione a U, mentre l'altra fa l'inversione a U,
    • provengono da direzioni ortogonali, l'una a sinistra gira a destra e l'altra non effettua l'inversione a U.

      Di seguito alcuni esempi di non collisione dei percorsi. Si noti che al terzo disegno qualsiasi percorso di N si scontrerebbe con il percorso di E, anche se N fa un'inversione di marcia.

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine

  1. Se due percorsi si scontrano, è necessario utilizzare altre regole. Se due veicoli si trovano sulla stessa strada prioritaria (vedi sotto), al veicolo viene dato il diritto di passaggio che:
    • viene dalla strada sul lato destro, se provengono da direzioni ortogonali
    • gira a destra se l'altra gira a sinistra
    • va dritto o gira a destra se l'altro fa un'inversione a U.

      In entrambi gli esempi di seguito, il veicolo E ha la precedenza sul veicolo S.

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine

Nell'esempio che segue va prima W, poi N, quindi E e l'ultima va a S.

inserisci qui la descrizione dell'immagine

Per questo caso particolare l'output del tuo programma dovrebbe essere:

1. W->S
2. N->S
3. E->S
4. S->S
  1. Tutti i conducenti usano gli indicatori di direzione e sanno dove vogliono andare tutti gli altri (per semplicità supponiamo che sia possibile distinguere tra la svolta a sinistra e la svolta a U).

  2. A volte alle strade vengono assegnati segni di priorità, che sono più importanti delle regole di cui sopra. Una strada con priorità più alta ha un segno di priorità ( immagine del segno di priorità ). Se la strada prioritaria non procede dritta, vengono utilizzati anche segnali aggiuntivi, come questo . Le strade con priorità inferiore hanno un segnale di rendimento o un segnale di stop (sono equivalenti). Nessuna o esattamente due strade diverse avranno una priorità più alta. L'utente del tuo programma dovrebbe essere in grado di inserire quali strade hanno priorità più alte (o più basse).

  3. Un veicolo che viene dalla strada con priorità più alta ha la precedenza su un veicolo proveniente da una strada con priorità inferiore, anche se si trova sul lato sinistro.
  4. Se i percorsi di due veicoli provenienti dalle strade con la stessa priorità si scontrano, sono attive le regole sopra il lato destro.

    Nell'esempio che segue le strade S e W hanno segni di priorità, il che significa che i veicoli su N ed E dovrebbero dare loro la strada. Il veicolo S ha la priorità sul veicolo W, perché si trova sul lato destro, quindi va per primo. Quindi va W, perché si trova sulla strada con priorità più alta di E. Il veicolo N ha la precedenza da E, perché si trova sul lato destro. Come l'ultimo va E.

inserisci qui la descrizione dell'immagine

Per questo caso particolare l'output del tuo programma dovrebbe essere:

1. S->W
2. W->N
3. N->S
4. E->W
  1. È possibile che un (e non più) veicolo sia un veicolo di emergenza , che ha la priorità indipendentemente dalla direzione da cui proviene o va e da quale segnale ha (va sempre per primo). Il programma dovrebbe consentire all'utente di inserire quale veicolo è un veicolo di emergenza. Considerando che sull'ultimo esempio N è un veicolo di emergenza, N va prima, poi S, W e come l'ultima E.

Per questo caso particolare con un veicolo di emergenza su N, l'output del tuo programma dovrebbe essere:

1. N->S
2. S->W
3. W->N
4. E->W
  1. Se due veicoli possono andare nello stesso momento (i loro percorsi non si scontrano e non devono lasciare il posto ad altri veicoli), il tuo programma dovrebbe scoprirlo e restituirli con lo stesso numero progressivo

    Nell'esempio che segue i percorsi di N ed E nonché di E e S o W ed E non si scontrano. Poiché S deve lasciare il posto a N e W lasciare il posto a S, S non può andare contemporaneamente con E, ecc. N e E possono. Quindi all'inizio N ed E vanno insieme, poi va S e W come ultimo.

inserisci qui la descrizione dell'immagine

L'output corretto del programma dovrebbe essere:

1. N->W
1. E->E
2. S->W
3. W->N

Sei libero di scegliere l'ordine delle linee 1( N->W / E->Eè equivalente a E->E / N->W)

  1. A volte il traffico può portare a una situazione irrisolvibile, che non consente a nessun veicolo di andare. Nella vita reale si risolve quando uno dei conducenti si dimette volontariamente dalla sua precedenza. Qui, il tuo programma dovrebbe produrre unsolvableecc., Come indicato nella prima parte della domanda.

    Di seguito è riportato un esempio di situazione irrisolvibile. E dovrebbe lasciare il posto a W, W dovrebbe lasciare il posto a S e S dovrebbe lasciare il posto a E.

inserisci qui la descrizione dell'immagine


3
Penso che dovrebbe essere definito un formato di input coerente. "L'input può avere qualsiasi struttura che ti piace" è una grande bandiera rossa. L'input può essere la soluzione?
Calvin's Hobbies,

@ Calvin'sHobbies Ho aggiornato la domanda
Voitcus

Qualche possibilità di ottenere un esempio di input / output per 1-2 casi?
Charlie Wynn,

Quindi la domanda (e presumo la soluzione) presuppone che le strade in questione siano guidate a destra?
Tersosauros,

Questo è esattamente come funziona Google Cars
coredump

Risposte:


8

Q, 645 byte

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);}

COMMENTI

In definitiva, non è un codice breve (né semplice). Può essere (gravemente) compattato, ma è lasciato come esercizio al lettore (ho dedicato troppo tempo a questo problema).

Ho incluso una soluzione commentata su più righe, ma suppongo che le nuove righe siano 1 byte e scarti i commenti (da / alla fine della riga) per contare le dimensioni

La difficoltà principale è comprendere appieno tutte le regole. L'ottimizzazione precoce della lunghezza del codice è incompatibile con lo sviluppo di una soluzione per un problema complesso. Né l'approccio bottom-up o top-down affronta bene il codice illeggibile.

Infine, ho sviluppato una tabella di decisione (matrice dei conflitti) con 16 righe e 16 colonne (per ogni direzione combinata con ogni possibile giro). I valori degli elementi sono 0 (compatibilità), 1 (preferenza per riga) o 2 (preferenza per colonna). Soddisfa tutti i test, non sono sicuro che tutte le possibili situazioni siano ben coperte

Il file di origine deve avere l'estensione k. Avvia l'interprete interattivo (gratuito per uso non commerciale, kx.com) e valuta al prompt (come mostrato nel paragrafo "test")

TEST

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

SPIEGAZIONE

La struttura di base è la "matrice di precedenza"

   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

Significato (per esempio)

  • m[NW][SE] ha valore 0 (entrambi i movimenti sono compatibili -concorrente-)
  • m[EW][SN] ha 1 valore (EW ha priorità su SN) NOTA.- Altri fattori prioritari possono alterare questa frase (veicoli di emergenza, priorità su strada, ..)
  • m[NE][SE] ha un valore di 2 (SE ha la priorità su NE) NOTA.- Altri fattori prioritari possono modificare questa frase (veicoli di emergenza, strada prioritaria, ..)

La matrice può essere costruita usando quattro tipi di sottomatrix (4x4)

  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

La matrice è completata da una funzione che assegna una priorità a ciascun movimento. Tale funzione tiene conto dei veicoli di emergenza, delle strade prioritarie, delle direzioni ortogonali, del tipo di svolta e dei veicoli "provenienti da destra"

Ordiniamo i movimenti per priorità e applichiamo i valori della matrice. La sottostruttura risultante include conflitti e priorità di ogni movimento.

  • analizziamo casi irrisolvibili (conflitti reciproci)
  • in caso contrario, selezioniamo l'elemento più prioritario e tutti i movimenti compatibili con esso e non incompatibili con i precedenti movimenti incompatibili e creiamo un insieme di movimenti che possono andare simultaneamente
  • Scrivi quel set di movimenti e ripeti il ​​resto dei candidati
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.