Pouvez-vous boucler sans planter?

14

Beaucoup d'entre nous connaissent le jeu Tron. Vous contrôlez un "lightcycle" placé sur une grille. Le cycle lumineux avance toujours (bien que vous contrôliez la direction) et laisse une trace permanente derrière lui. Si vous tombez sur un sentier, vous vous écrasez!

Le but ici est de déterminer si un chemin donné est une boucle valide, c'est-à-dire qu'il revient à son point de départ sans "planter". Pour ce faire, nous supposons que nous commençons au point (0,0). Une entrée est donnée sous la forme N2E1S2W1, avec une série de directions cardinales ( Nis north, Eis east, etc.), chacune suivie de la distance à parcourir dans cette direction. Dans cet exemple, vous voyageriez

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 chemin est considéré comme valide s'il se termine (0,0)sans visiter aucune autre coordonnée plus d'une fois (il visite (0,0)exactement deux fois. Une fois au début et une fois à la fin). Gardez à l'esprit que dans l'exemple ci-dessus, pour aller de (0,0)à (0,2), nous visitons nécessairement (0,1)aussi.

Autres exemples:

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

Votre sortie peut être sous n'importe quelle forme tant qu'elle donne la même sortie pour toute valeur véridique ou falsey.

L'entrée peut être considérée comme une chaîne ou comme une liste de caractères, sous la forme S1N2E3... ou SNNEEE... Il n'y a pas non plus de limite stricte sur la taille de la grille, mais supposez que l'entrée ne va rien déborder. Tant que le code est fondamentalement solide, il n'est pas crucial de gérer des cas comme N99999999999999.

REMARQUE: Vous pouvez évaluer les cas N1S1, E1W1, S1N1et W1E1vous aimeriez cependant. Ce sont des voies techniquement valables, mais elles vont à l'encontre de l'esprit "Tron" du défi.

Notation

Il s'agit de , donc la réponse la plus courte l'emporte!

Lord Farquaad
la source
N1S1doit être vrai pour être cohérent avec vos définitions car il atteint (0, 0)deux fois et (0, 1)une fois, ce qui est valide selon votre définition.
HyperNeutrino
Puis-je prendre Ncomme 1j, Ecomme 1, Scomme -1jet Wcomme -1?
Leaky Nun
@LeakyNun Je pense que je suis d'accord avec ça, puisque tout le monde devrait plus ou moins faire quelque chose comme ça le capot de toute façon. Assurez-vous simplement de le préciser dans votre réponse.
Lord Farquaad
1
@HyperNeutrino mais d'un point de vue Tron, votre cycle de lumière passe par (0, 0,5) deux fois, même si l'entrée ne vous mettra jamais à un tel point. C'est pourquoi je pense que l'on a une sortie flexible (même si pour la plupart des langues, il sera plus facile de retourner vrai)
Value Ink
1
@steenbergh (0,0) n'est pas dans le coin, vous pouvez donc aller en dessous ou à gauche de celui-ci; même les deux si vous vous sentez fou! En outre, il n'y a pas de limite stricte sur la taille de la grille, mais supposez simplement que l'entrée ne va rien déborder. Tant que le code est fondamentalement sain, je m'en fiche s'il ne peut pas gérer des entrées commeN99999999999999
Lord Farquaad

Réponses:

6

JavaScript, 247 200 octets

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}

nest une fonction de la chaîne d'entrée squi renvoie 1pour vrai et 0pour faux

Voici une version non golfée pour référence / explication:

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
la source
Supprimer des espaces
HyperNeutrino
n'a pas remarqué cela, merci
WaffleCohn
Il semble que ce containsne soit une fonction dans aucun dialecte de javascript. Pourriez-vous spécifier le dialecte?
Leaky Nun
J'utilisais juste la console chromée pour tester - cela fonctionne parfaitement là
WaffleCohn
En fait, cela fonctionne également dans ma console chromée ... mais peut-être envisageriez-vous de le changer en une réponse plus universelle?
Leaky Nun
5

Python 3 , 236 161 150 octets

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

Essayez-le en ligne!

-75 octets grâce à Leaky Nun
-11 octets grâce à Leaky Nun Ou, si nous sommes autorisés à prendre en entrée une liste de nombres complexes décodés de longueur:

Python 2 , 85 73 octets

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

Essayez-le en ligne!

-12 octets grâce à M. Xcoder / -9 octets grâce à Leaky Nun (fusionné en une seule modification)

Cela me semble trop long lol

HyperNeutrino
la source
3
Tant qu'elle est inférieure à 10 fois la solution Pyth, elle n'est pas trop longue.
Leaky Nun
@LeakyNun lol okay: P
HyperNeutrino
161 octets
Leaky Nun
@LeakyNun oh snap nice. voir trop longtemps, comme je l'ai dit: P
HyperNeutrino
76 octets
Leaky Nun
3

Gelée , 14 12 octets

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

C'est la première fois que je joue au golf à Jelly. Les suggestions sont les bienvenues.

L'entrée est un tableau de [direction, distance]paires, où la direction est donnée sous forme de nombre complexe.

Explication:

Œṙ+\µÇȧṛ/¬$   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
la source
Devrait échouer le dernier cas.
Leaky Nun
0

Rétine , 86 octets

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

Essayez-le en ligne! Le lien inclut des cas de test. Explication:

\d+
$*

Convertissez les nombres en unaire.

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

La longueur de course décode les lettres. N111doit se transformer en NNN, donc un est soustrait de chaque nombre unaire, puis chaque 1 duplique la lettre précédente.

.
 $`$&¶

Générez tous les préfixes (c'est-à-dire les points sur le chemin) en tant que lignes distinctes. Un espace est préfixé pour éviter les problèmes avec les lignes vides.

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

Triez toutes les lettres de chaque ligne dans l'ordre, puis supprimez les paires correspondantes. On se retrouve avec un code unique pour tout point donné sur la grille.

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

Vérifiez l'une des deux choses suivantes: a) le dernier point ne se termine pas dans un espace (c'est-à-dire que la boucle ne s'est pas fermée), ou deux points en double dans le chemin. Si le chemin est valide, toutes les vérifications échouent et le résultat est zéro.

^0

Inversez le résultat.

Neil
la source
0

Perl, 140

Fonctionne avec une entrée de chaîne. Je peux peut-être raccourcir avec le tableau, mais j'en doute. Heureux pour toute autre aide au 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)}
bytepusher
la source