Schaffst du eine Schleife, ohne zu stürzen?

14

Viele von uns kennen das Spiel Tron. Sie steuern ein "Lightcycle", das auf einem Raster platziert ist. Das Lightcycle fährt immer vorwärts (obwohl Sie die Richtung steuern) und hinterlässt eine permanente Spur. Wenn Sie auf eine Spur stoßen, stürzen Sie ab!

Das Ziel hierbei ist, festzustellen, ob ein bestimmter Pfad eine gültige Schleife ist, das heißt, er kehrt ohne "Absturz" an seinen Ausgangspunkt zurück. Dazu gehen wir davon aus, dass wir am Punkt beginnen (0,0). Eine Eingabe erfolgt in der Form N2E1S2W1, mit einer Reihe von Himmelsrichtungen ( Nist north,E is eastusw.), gefolgt von der Entfernung, um diese Richtung zurückzulegen. In diesem Beispiel würden Sie reisen

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

Ein Pfad gilt als gültig, wenn er um endet, (0,0)ohne eine andere Koordinate mehr als einmal zu besuchen (er wird (0,0)genau zweimal aufgerufen. Einmal am Anfang und einmal am Ende). Denken Sie daran, als im obigen Beispiel, um von (0,0)zu erhalten (0,2), müssen wir auch besuchen (0,1).

Andere Beispiele:

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

Ihre Ausgabe kann in beliebiger Form erfolgen, sofern sie für alle wahrheitsgemäßen oder falschen Werte dieselbe Ausgabe liefert.

Die Eingabe kann als Zeichenfolge oder als Liste von Zeichen entweder in der Form S1N2E3... oder SNNEEE... verwendet werden. Es gibt auch keine feste Grenze für die Rastergröße, aber es wird davon ausgegangen, dass die Eingabe nicht überläuft. Solange der Code grundsätzlich solide ist, ist es nicht entscheidend, Fälle wie N99999999999999.

Hinweis: Sie können die Fälle bewerten N1S1, E1W1, S1N1, und W1E1aber Sie möchten. Sie sind technisch gültige Wege, aber sie widersprechen dem "Tron" -Geist der Herausforderung.

Wertung

Das ist , also gewinnt die kürzeste Antwort!

Lord Farquaad
quelle
N1S1sollte wahr sein, um mit Ihren Definitionen konsistent zu sein, da es (0, 0)zweimal und (0, 1)einmal erreicht, was unter Ihrer Definition gültig ist.
HyperNeutrino
Kann ich Nas 1j, Eas 1, Sas -1jund Was nehmen -1?
Undichte Nonne
@LeakyNun Ich denke ich bin damit einverstanden, da jeder sowieso mehr oder weniger sowas von die Motorhaube machen sollte. Stellen Sie einfach sicher, dass Sie dies in Ihrer Antwort angeben.
Lord Farquaad
1
@HyperNeutrino aber aus Sicht von Tron durchläuft Ihr Lightcycle zweimal (0, 0,5), auch wenn Sie durch die Eingabe nie an einen solchen Punkt gelangen. Deshalb denke ich, dass man eine flexible Ausgabe hat (obwohl es für die meisten Sprachen einfacher sein wird, true zurückzugeben)
Value Ink
1
@steenbergh (0,0) ist nicht in der Ecke, Sie können also unter oder links davon gehen. sogar beides, wenn du verrückt bist! Außerdem gibt es keine feste Grenze für die Rastergröße, sondern nur die Annahme, dass die Eingabe nicht überläuft. Solange der Code grundsätzlich solide ist, ist es mir egal, ob er Eingaben wieN99999999999999
Lord Farquaad

Antworten:

8

Pyth , 44 39 Bytes

&!eJsM._smm^.j)x"NESW"hdstd:z".\d+"1{IJ

Testsuite .

Undichte Nonne
quelle
6

JavaScript, 247 200 Bytes

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}

nist eine Funktion der Eingabezeichenfolge s, die 1für true und 0false zurückgibt

Hier ist eine ungolfed Version als Referenz / Erklärung:

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"))

WaffelCohn
quelle
Leerzeichen entfernen
HyperNeutrino
habe das nicht bemerkt, danke
WaffleCohn
Es scheint, dass dies containsin keinem Dialekt von Javascript eine Funktion ist. Könnten Sie den Dialekt angeben?
Undichte Nonne
Ich habe gerade die
Chromkonsole
Eigentlich funktioniert es auch in meiner Chromkonsole ... aber vielleicht würden Sie darüber nachdenken, es in eine universellere Antwort umzuwandeln?
Undichte Nonne
5

Python 3 , 236 161 150 Bytes

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])

Probieren Sie es online!

-75 Bytes dank Leaky Nun
-11 Bytes dank Leaky Nun Oder, wenn wir Eingaben als Liste von längencodierten komplexen Zahlen annehmen dürfen:

Python 2 , 85 73 Bytes

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

Probieren Sie es online!

-12 Bytes dank Mr. Xcoder / -9 Bytes dank Leaky Nun (zusammengeführt in einer Bearbeitung)

Das ist mir zu lang, lol

HyperNeutrino
quelle
3
Solange es kürzer als das Zehnfache der Pyth-Lösung ist, ist es nicht zu lang.
Undichte Nonne
@LeakyNun lol okay: P
HyperNeutrino
161 Bytes
Undichte Nonne
@LeakyNun oh schnapp schön. zu lange sehen, wie gesagt: P
HyperNeutrino
76 Bytes
Undichte Nonne
3

Jelly , 14 12 Bytes

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

Ich spiele zum ersten Mal Golf in Jelly. Vorschläge sind willkommen.

Die Eingabe erfolgt als Array von [direction, distance]Paaren, wobei die Richtung als komplexe Zahl angegeben wird.

Erläuterung:

Œṙ+\µÇȧṛ/¬$   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
Esolanging Fruit
quelle
Sollte im letzten Fall scheitern.
Undichte Nonne
0

Netzhaut , 86 Bytes

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

Probieren Sie es online! Link enthält Testfälle. Erläuterung:

\d+
$*

Wandle die Zahlen in unäre um.

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

Lauflänge dekodieren die Buchstaben. N111muss in verwandeln NNN, so dass man von jeder unären Zahl subtrahiert wird und dann jede 1 den vorherigen Buchstaben dupliziert.

.
 $`$&¶

Generieren Sie alle Präfixe (dh Punkte auf dem Pfad) als separate Linien. Ein Leerzeichen wird vorangestellt, um Probleme mit leeren Zeilen zu vermeiden.

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

Sortieren Sie alle Buchstaben in jeder Zeile in der richtigen Reihenfolge und löschen Sie dann übereinstimmende Paare. Am Ende erhalten wir einen eindeutigen Code für einen bestimmten Punkt im Raster.

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

Überprüfen Sie Folgendes: a) Der letzte Punkt endet nicht in einem Leerzeichen (dh die Schleife wurde nicht geschlossen) oder zwei doppelte Punkte im Pfad. Wenn der Pfad gültig ist, schlagen alle Überprüfungen fehl und das Ergebnis ist Null.

^0

Kehre das Ergebnis um.

Neil
quelle
0

Perl, 140

Funktioniert mit Zeichenketteneingabe. Vielleicht kann ich mit Array verkürzen, aber ich bezweifle es. Gerne für jede weitere Golfhilfe :)

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)}
Byteschieber
quelle