Czy potrafisz zapętlać się bez awarii?

14

Wielu z nas zna grę Tron. Kontrolujesz „lekki rower” umieszczony na siatce. Lekki rower zawsze porusza się do przodu (chociaż kontrolujesz kierunek) i pozostawia za sobą ślad. Jeśli wpadniesz na ślad, rozbijesz się!

Celem jest ustalenie, czy dana ścieżka jest prawidłową pętlą, tzn. Wraca do punktu początkowego bez „awarii”. Aby to zrobić, zakładamy, że zaczynamy od punktu (0,0). Dane wejściowe są podawane w postaci N2E1S2W1szeregu kardynalnych kierunków ( Njest north, Ejest eastitd.), Po których następuje odległość do przebycia w tym kierunku. W tym przykładzie podróżowałbyś

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

Ścieżka jest uważana za ważną, jeśli kończy się na (0,0)nie odwiedzając żadnej innej współrzędnej więcej niż raz (odwiedza (0,0)dokładnie dwa razy. Raz na początku i raz na końcu). Pamiętaj, że w powyższym przykładzie, aby dostać się (0,0)do (0,2), koniecznie odwiedź (0,1)również.

Inne przykłady:

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

Twój wynik może być w dowolnej formie, pod warunkiem, że daje to samo wyjście dla dowolnej wartości prawdziwej lub falsey.

Dane wejściowe można traktować jako ciąg znaków lub listę znaków, w formie S1N2E3... lub SNNEEE... Nie ma również sztywnego limitu rozmiaru siatki, ale należy założyć, że dane wejściowe niczego nie przepełnią. Tak długo, jak kod jest zasadniczo poprawny, tak ważne jest, aby obsługiwać takie przypadki N99999999999999.

UWAGA: Można oceniać przypadki N1S1, E1W1, S1N1, a W1E1jednak chciałbyś. Są to technicznie ważne ścieżki, ale są sprzeczne z duchem wyzwania „Tron”.

Punktacja

To jest , więc wygrywa najkrótsza odpowiedź!

Lord Farquaad
źródło
N1S1powinna być zgodna z twoimi definicjami, ponieważ osiąga (0, 0)dwa razy i (0, 1)raz, co jest ważne w twojej definicji.
HyperNeutrino,
Mogę wziąć Njak 1j, Ejak 1, Sjak -1j, i Wjak -1?
Leaky Nun
@LeakyNun Myślę, że nie mam nic przeciwko, ponieważ każdy powinien mniej więcej robić coś takiego. Upewnij się tylko, że podałeś to w swojej odpowiedzi.
Lord Farquaad,
1
@HyperNeutrino, ale z punktu widzenia Tron Twój rower lekki przechodzi dwukrotnie (0, 0,5), nawet jeśli dane wejściowe nigdy nie doprowadzą cię do takiego punktu. Dlatego uważam, że jeden ma elastyczny wynik (chociaż w przypadku większości języków łatwiej będzie zwrócić wartość true)
Value Ink
1
@steenbergh (0,0) nie jest w rogu, więc możesz zejść pod lub na lewo od niego; nawet jeśli czujesz się szalony! Ponadto nie ma twardego limitu rozmiaru siatki, ale po prostu załóż, że dane wejściowe niczego nie przepełnią. Tak długo, jak kod jest zasadniczo poprawny, nie obchodzi mnie, czy nie obsługuje takich danych wejściowych, jakN99999999999999
Lord Farquaad, 17-17

Odpowiedzi:

6

JavaScript, 247 200 bajtów

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}

njest funkcją ciągu wejściowego, sktóra zwraca wartość 1true i 0false

Oto nieprzygotowana wersja dla odniesienia / objaśnienia:

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

WaffleCohn
źródło
nie zauważyłem tego, dzięki
WaffleCohn
Wygląda na containsto, że nie jest to funkcja w żadnym dialekcie języka javascript. Czy możesz podać dialekt?
Leaky Nun
Właśnie testowałem chromowaną konsolę - działa tam doskonale
WaffleCohn,
Właściwie to działa również w mojej chromowanej konsoli ... ale może zastanowisz się nad zmianą na bardziej uniwersalną odpowiedź?
Leaky Nun
5

Python 3 , 236 161 150 bajtów

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

Wypróbuj online!

-75 bajtów dzięki Leaky Nun
-11 bajtów dzięki Leaky Nun Lub, jeśli wolno nam przyjmować dane wejściowe jako listę zdekodowanych liczb zespolonych:

Python 2 , 85 73 bajtów

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

Wypróbuj online!

-12 bajtów dzięki Mr. Xcoder / -9 bajtów dzięki Leaky Nun (połączone w jedną edycję)

To wydaje mi się zbyt długie, lol

HyperNeutrino
źródło
3
Tak długo, jak jest krótszy niż 10-krotnie rozwiązanie Pyth, nie jest zbyt długi.
Leaky Nun
@LeakyNun lol w porządku: P
HyperNeutrino
161 bajtów
Leaky Nun
@LeakyNun oh snap nice. patrz zbyt długo, jak powiedziałem: P
HyperNeutrino
76 bajtów
Leaky Nun
3

Galaretka , 14 12 bajtów

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

To mój pierwszy raz w golfa w Jelly. Sugestie są mile widziane.

Dane wejściowe są w postaci tablicy [direction, distance]par, gdzie kierunek jest podany jako liczba zespolona.

Wyjaśnienie:

Œṙ+\µÇȧṛ/¬$   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
źródło
Powinien zawieść ostatni przypadek.
Leaky Nun
0

Siatkówka , 86 bajtów

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

Wypróbuj online! Link zawiera przypadki testowe. Wyjaśnienie:

\d+
$*

Konwertuj liczby na unary.

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

Długość przebiegu dekoduje litery. N111musi się zmienić NNN, więc odejmuje się jeden od każdej liczby jednoargumentowej, a następnie każdy 1 powiela poprzednią literę.

.
 $`$&¶

Wygeneruj wszystkie prefiksy (tj. Punkty na ścieżce) jako osobne linie. Spacja ma prefiks, aby uniknąć problemów z pustymi liniami.

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

Posortuj wszystkie litery w każdym wierszu w kolejności, a następnie usuń pasujące pary. W rezultacie otrzymujemy unikalny kod dla dowolnego punktu na siatce.

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

Sprawdź jedną z dwóch rzeczy: a) ostatni punkt nie kończy się spacją (tj. Pętla się nie zamyka) lub dwa zduplikowane punkty na ścieżce. Jeśli ścieżka jest poprawna, wszystkie testy kończą się niepowodzeniem, a wynik wynosi zero.

^0

Odwróć wynik.

Neil
źródło
0

Perl, 140

Działa z ciągiem wejściowym. Być może mogę skrócić za pomocą tablicy, ale wątpię w to. Chętnie pomożemy w dalszej grze w golfa :)

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)}
bytepusher
źródło