Puoi fare un loop senza crash?


14

Molti di noi hanno familiarità con il gioco Tron. Controlli un "ciclo di luce" posizionato su una griglia. Il ciclo di luce si sposta sempre in avanti (anche se controlli la direzione) e lascia dietro di sé una scia permanente. Se ti imbatti in un sentiero, ti schianti!

L'obiettivo qui è determinare se un determinato percorso è un ciclo valido, cioè ritorna al suo punto di partenza senza "crash". Per fare ciò, supponiamo di iniziare dal punto (0,0). Viene fornito un input nella forma N2E1S2W1, con una serie di direzioni cardinali ( Nis north, Eis easte così via), ciascuna seguita dalla distanza per percorrere quella direzione. In questo esempio, viaggeresti

N2 : North 2 to (0,2)
E1 : East 1  to (1,2)
S2 : South 2 to (1,0)
W1 : West 1  to (0,0)

Un percorso è considerato valido se termina (0,0)senza visitare altre coordinate più di una volta (visita (0,0)esattamente due volte. Una volta all'inizio e una volta alla fine). Ricorda che nell'esempio sopra, per andare da (0,0)a (0,2), visitiamo necessariamente anche noi (0,1).

Altri esempi:

input        -> output
N1E1S1W1     -> true
N1E1N1E1S2W2 -> true
N1S1E1W1     -> false     // Visits (0,0) 3 times
N4E2S2W4S2E2 -> false     // Visits (0,2) twice
N3E2S3       -> false     // Does not return to (0,0)
N1S1         -> anything  //I don't care how you evaluate this case

Il tuo output può essere in qualsiasi forma purché fornisca lo stesso output per qualsiasi valore di verità o falsità.

L'input può essere preso come una stringa o come un elenco di caratteri, sia nella forma S1N2E3... o SNNEEE... Non c'è anche alcun limite rigido per la dimensione della griglia, ma si supponga che l'input non abbia troppopieno. Fintanto che il codice è fondamentalmente valido, non è fondamentale gestire casi simili N99999999999999.

NOTA: È possibile valutare i casi N1S1, E1W1, S1N1, e W1E1tuttavia si desidera. Sono percorsi tecnicamente validi, ma vanno contro lo spirito "Tron" della sfida.

punteggio

Questo è , quindi vince la risposta più breve!


N1S1dovrebbe essere vero per essere coerente con le tue definizioni perché raggiunge (0, 0)due volte e (0, 1)una volta, il che è valido sotto la tua definizione.
HyperNeutrino,

Posso prendere Ncome 1j, Ecome 1, Scome -1je Wcome -1?
Leaky Nun,

@LeakyNun Penso di essere d'accordo, dato che tutti dovrebbero fare qualcosa di simile al cappuccio comunque. Assicurati di specificarlo nella tua risposta.
Lord Farquaad,

1
@HyperNeutrino ma dal punto di vista di Tron, il tuo ciclo di luce passa attraverso (0, 0,5) due volte, anche se l'ingresso non ti metterà mai in quel punto. Ecco perché penso che uno abbia un output flessibile (anche se per la maggior parte delle lingue sarà più semplice restituire true)
Value Ink

1
@steenbergh (0,0) non è nell'angolo, quindi puoi andare sotto o alla sua sinistra; anche entrambi se ti senti pazzo! Inoltre, non vi è alcun limite rigido alla dimensione della griglia, ma supponiamo che l'input non abbia troppopieno. Finché il codice è fondamentalmente valido, non mi interessa se non è in grado di gestire input comeN99999999999999
Lord Farquaad,

Risposte:



6

JavaScript, 247 200 byte

n=s=>{r=s.match(/\w\d+/g)
x=y=z=0
e=""
for(d of r){a=d[0]
b=d.slice(1)
while(b--){
y+=a=="N"
y-=a=="S"
x+=a=="E"
x-=a=="W"
p=[x,y]+";"
if(~e.indexOf(p))if(!x&!y)z++
else return 0
e+=p}}return!x&!y&!z}

nè una funzione della stringa di input sche restituisce 1true e 0false

Ecco una versione non modificata per riferimento / spiegazione:

function n(s)
{
    var dir = s.match(/\w\d+/g);
    var x = y = z = 0;
    var been = "";
    for (d of dir)
    {
        var a = d[0];
        var b = 1*d.substring(1);
        while(b-- > 0)
        {
            if (a == "N") y++;
            if (a == "S") y--;
            if (a == "E") x++;
            if (a == "W") x--;
            var pt = [x,y] + ";";
            if (~been.indexOf(pt))
                if (x==0 && y==0)
                    z++;
                else
                    return false;
            been += pt;
        }
    }
    return (x == 0 && y==0 && z == 0);
}

n=s=>{r=s.match(/\w\d+/g)
x=y=z=0
e=""
for(d of r){a=d[0]
b=d.slice(1)
while(b--){
y+=a=="N"
y-=a=="S"
x+=a=="E"
x-=a=="W"
p=[x,y]+";"
if(~e.indexOf(p))if(!x&!y)z++
else return 0
e+=p}}return!x&!y&!z}

console.log(n("N1E1S1W1"))
console.log(n("N1E1N1E1S2W2"))
console.log(n("N1S1E1W1"))
console.log(n("N4E2S2W4S2E2"))
console.log(n("N3E2S3"))



non
me

Sembra che containsnon sia una funzione in nessun dialetto di JavaScript. Potresti specificare il dialetto?
Leaky Nun,

Stavo solo usando la console Chrome per testare - funziona perfettamente lì
WaffleCohn

In realtà funziona anche nella mia console Chrome ... ma forse potresti prendere in considerazione di cambiarlo in una risposta più universale?
Leaky Nun,

5

Python 3 , 236 161 150 byte

import re
p=0
a=[]
for i in''.join(s[0]*int(s[1:])for s in re.findall(r".\d+",input())):p+=1j**"NESW".find(i);a+=[p]
print(len({*a})-len(a)==0==a[-1])

Provalo online!

-75 byte grazie a Leaky Nun
-11 byte grazie a Leaky Nun Oppure, se ci è permesso prendere input come un elenco di numeri complessi decodificati in lunghezza:

Python 2 , 85 73 byte

c=0;k=[]
for i in input():c+=i;k+=[c]
print(k[-1]==0==len(set(k))-len(k))

Provalo online!

-12 byte grazie a Mr. Xcoder / -9 byte grazie a Leaky Nun (fusa in una modifica)

Mi sembra troppo lungo lol


3
Finché è più breve di 10 volte la soluzione Pyth, non è troppo lungo.
Leaky Nun,

@LeakyNun lol ok: P
HyperNeutrino,


@LeakyNun oh snap nice. vedi troppo a lungo, come ho detto: P
HyperNeutrino,


3

Gelatina , 14 12 byte

Œṙ+\µQ⁼ȧṛ/¬$

Questa è la prima volta che gioco a golf a Jelly. Suggerimenti sono ben accetti

L'input è un array di [direction, distance]coppie, in cui la direzione è data come un numero complesso.

Spiegazione:

Œṙ+\µÇȧṛ/¬$   Main link. Argument: n     = [[i, 3], [1, 2], [-i, 3]]
Œṙ            Run-length decode          = [i, i, i, 1, 1, -i, -i, -i]
  +\          Cumulative sum             = [i, 2i, 3i, 3i+1, 3i+2, 2i+2, i+2, i]
    µ         Begin a new monadic chain
     Q        Remove duplicates          = [i, 2i, 3i, 3i+1, 3i+2, 2i+2, i+2]
      ⁼       Equal to original?         = 0
           $  Make a monadic link:
        ṛ/      Reduce by right argument   = i
                (Gets the last element)
          ¬     Logical NOT:               = 0
       ȧ      Logical AND the two values = 0

Dovrebbe fallire l'ultimo caso.
Leaky Nun,

0

Retina , 86 byte

\d+
$*
1(1*)
$1
+`(.)1
$1$1
.
 $`$&¶
%O`.
+`NS|E(.*)W
$1
M`\w$|(?m)(^.+$)(?s).+^\1$
^0

Provalo online! Il link include casi di test. Spiegazione:

\d+
$*

Converti i numeri in unario.

1(1*)
$1
+`(.)1
$1$1

La lunghezza decodifica delle lettere. N111deve trasformarsi in NNN, quindi uno viene sottratto da ciascun numero unario e quindi ogni 1 duplica la lettera precedente.

.
 $`$&¶

Genera tutti i prefissi (cioè i punti sul percorso) come linee separate. Uno spazio è prefissato per evitare problemi con linee vuote.

%O`.
+`NS|E(.*)W
$1

Ordinare tutte le lettere in ciascuna riga in ordine e quindi eliminare le coppie corrispondenti. Finiamo con un codice univoco per ogni dato punto sulla griglia.

M`\w$|(?m)(^.+$)(?s).+^\1$

Verifica una delle due cose: a) l'ultimo punto non termina in uno spazio (ovvero il loop non si è chiuso) o due punti duplicati nel percorso. Se il percorso è valido, tutti i controlli falliscono e il risultato è zero.

^0

Invertire il risultato.


0

Perl, 140

Funziona con input stringa. Forse posso accorciare con l'array, ma ne dubito. Felice per ogni ulteriore aiuto sul golf :)

sub w{$i=$_[0];%d=(E,[0],S,[1,-1],W,[0,-1]);$i=~s/(.)(.)/($d,$o)=(@{$d{$1}},1,1);for(1..$2){$s[$d]+=$o;$r+=$d{"@s"}++}/eg;!($s[0]+$s[1]+$r)}
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.