Würfelpfade auf einem Gitter

Sep 23 2020

Sie platzieren einen Standardwürfel am Ursprung eines 2D-Gitters, das sich unendlich in alle Richtungen erstreckt. Sie platzieren den Würfel so, dass die 1 nach oben zeigt, die 2 in die negative y-Richtung zeigt und die 3 in die positive x-Richtung zeigt, wie in der folgenden Abbildung gezeigt:

Anschließend führen Sie eine Reihe von Bewegungen mit dem Würfel aus, indem Sie ihn um 90 Grad in Bewegungsrichtung drehen. Wenn Sie beispielsweise zuerst den Würfel in die negative x-Richtung drehen würden, wäre eine 3 nach oben gerichtet, die 2 würde in die negative y-Richtung zeigen und eine 6 würde in die positive x-Richtung zeigen.

Die Reihe der Bewegungen +y, +y, +x, +x, -yist in der folgenden Abbildung zusammen mit dem Netz des Würfels zur Verdeutlichung dargestellt (manchmal wird das Netz als "rechtshändiger Würfel" bezeichnet).

Wir lesen dann nach jeder Bewegung die Oberseite des Würfels ab. In diesem Fall würde es lauten 2, 6, 4, 1, 2, was wir einen Würfelpfad nennen . Beachten Sie, dass wir die Oberseite des Würfels nicht in ihrer Ausgangsposition einschließen, sondern immer 1.

Wenn der Pfad des Würfels so ist, dass er zu dem Quadrat zurückkehrt, auf dem er am Ende seiner Bewegung begonnen hat, nennen wir dies einen Würfelpfad, der zum Ursprung zurückkehrt .

Herausforderung

Wenn bei einem nicht leeren Würfelpfad als Eingabe (in einer Liste oder einem anderen vernünftigen Format) ein wahrheitsgemäßer Wert gedruckt wird, wenn der Würfelpfad zum Ursprung zurückkehrt, andernfalls ein falscher Wert. Beachten Sie, dass:

  • Die von Ihnen ausgegebenen Wahrheits- und Falschwerte müssen nicht konsistent sein, können jedoch nicht ausgetauscht werden (z. B. einen Falschwert für einen Pfad ausgeben, der zum Ursprung zurückkehrt, und ansonsten einen Wahrheitswert).
  • Die Eingabe ist gut geformt und repräsentiert einen gültigen Würfelpfad.
  • Es gibt keine Begrenzung, wie weit der Würfel vom Ursprung abweichen kann.

Testfälle

Path                            -> Output
2,1                             -> true
3,1                             -> true
5,4,1,5                         -> true
2,4,1,2                         -> true
4,2,4,1                         -> true
2,4,6,2,4,6,5,4                 -> true
2,4,5,1,4,5,3,6,5,1             -> true
5,6,2,3,5,4,6,3,1,5,6,2         -> true
2,4,1,3,5,1,3,5,6,3,5,6,4,5,6,2 -> true
2                               -> false
4,5                             -> false
5,1,2                           -> false
5,6,2,1                         -> false
5,4,6,5,4,6                     -> false
5,6,4,1,5,4,2,6,5,4             -> false
5,1,2,1,5,6,5,1,2,6,4           -> false
4,6,3,1,5,6,2,1,3,6,4,1         -> false

Wertung

Der kürzeste Code in Bytes gewinnt.

Antworten

12 Arnauld Sep 23 2020 at 17:24

JavaScript (ES6),  142 ... 122  121 Byte

Erwartet eine Reihe von Zeichen, z ['5','1','2']. Gibt 0 oder 1 zurück .

a=>a.map(n=>D=D.map((_,i)=>D['504405076067'[d*6+i>>1]^i],p+=[w=a.length,-w,1,-1][d=D.indexOf(n)]),p=0,D=[...'254316'])|!p

Probieren Sie es online aus!

Wie?

Das Array D[]enthält die Nennwerte in der folgenden Reihenfolge:

 index |    0   |    1   |    2   |    3   |    4   |    5
-------+--------+--------+--------+--------+--------+--------
 face  |  front | behind |  left  |  right |   top  | bottom

Wir beginnen mit D = ['2','5','4','3','1','6']der anfänglichen Ausrichtung des Chips, wie in der Herausforderung beschrieben, unter Verwendung dieser Codierung.

Die Richtung dder nächsten Bewegung ist die 0-indizierte Position der neuen Oberseite in D[]:

 index (d) |   0   |   1   |   2   |   3
-----------+-------+-------+-------+-------
 direction |  up   |  down | right |  left

Wenn Sie sich in Richtung bewegen d, ist die i-te Fläche im aktualisierten Würfel die Fläche an der folgenden Position im vorherigen Würfel:

   i = | 0 | 1 | 2 | 3 | 4 | 5
-------+---+---+---+---+---+---
 d = 0 | 5 | 4 | 2 | 3 | 0 | 1
 d = 1 | 4 | 5 | 2 | 3 | 1 | 0
 d = 2 | 0 | 1 | 5 | 4 | 2 | 3
 d = 3 | 0 | 1 | 4 | 5 | 3 | 2

Diese Tabelle ist mit folgendem Ausdruck codiert:

'504405076067'[d * 6 + i >> 1] ^ i

Probieren Sie es online aus!

Bei jeder Iteration aktualisieren wir D[]und die Position p. Wir fügen \ hinzu$\pm 1\$zu \$p\$bei horizontaler Bewegung oder \$\pm w\$Wenn Sie sich vertikal bewegen, wo \$w\$ist die Länge des Eingabearrays (eine Obergrenze der Entfernung, die in eine einzelne Richtung zurückgelegt werden kann). Wir testen, ob wir am Ende des Prozesses wieder an unserem Ausgangspunkt sind.

8 xash Sep 23 2020 at 18:01

J , 79 Bytes

Nimmt den Würfelpfad als umgekehrte Liste von 0 bis 5 in Kästchen auf.

0 0-:[:+/(0,(,-@|.)=i.2){~]i.~&>[:}.(]A.~0 224 283 389 489{~i.~)&.>/\.@,&(<i.6)

Probieren Sie es online aus!

Wie es funktioniert

Wir haben die Startwürfel als Liste 0 1 2 3 4 5. Auf der Suche nach der nächsten oberen Ziffer haben wir entweder 1 2 3 4als Index ( 0und 5wären illegale Züge). Unter Verwendung der Anagrammindizes 224 283 389 489permutieren wir die Liste und führen einen Würfelzug aus. Wir tun dies für den gesamten Weg und sammeln die Zwischenergebnisse : 0 1 2 3 4 5│4 0 2 3 5 1│3 0 4 1 5 2. Nachdem wir nach den Indizes gesucht haben, ordnen wir sie erneut Koordinationsänderungen zu _1 0, 0 _1, 1 0, 0 1, fassen sie zusammen und prüfen, ob sie bei enden 0 0.

Es sollte eine Byte-Einsparung erfolgen, indem die Würfelnummern 6 bis 4, 5 bis 3,…, 1 bis 5 neu zugeordnet werden, um die beiden Dummy-Nullen ( 0,und 0 ) durch Verschieben der möglichen Indizes auf zu speichern 0 1 2 3. Aber das fühlt sich so falsch an, dass ich zuerst versuchen werde, eine andere Lösung zu finden. :-)

7 Neil Sep 23 2020 at 19:18

Holzkohle , 55 48 Bytes

≔324516θFS«≔⌕θιιM✳⊗ι≔⭆§⪪”)⊟?2p}Þ↔~>”⁶ι§θIκ軬∨ⅈⅉ

Probieren Sie es online aus! Der Link führt zur ausführlichen Version des Codes. Nimmt die Eingabe als Ziffernfolge und gibt einen Charcoal-Booleschen Wert aus, dh -für zurück am Ursprung ein Leerzeichen, wenn nicht (+2 Byte, um das Leerzeichen zu entfernen). Erläuterung:

≔324516θ

Die Ziffern auf dem Würfel in der Reihenfolge rechts, oben, links, unten, oben, unten.

FS«

Durchlaufen Sie die Eingangsziffern.

≔⌕θιι

Finden Sie heraus, in welche Richtung der Würfel gewürfelt wurde.

M✳⊗ι

Bewegen Sie sich in diese Richtung.

≔⭆§⪪”)⊟?2p}Þ↔~>”⁶ι§θIκ軬∨ⅈⅉ

Lassen Sie die Ziffern 514302 052413 415320 042531je nach Richtung mithilfe einer Nachschlagetabelle an ihre neuen Positionen .

»¬∨ⅈⅉ

Sind wir wieder am Ursprung gelandet?

6 xnor Sep 25 2020 at 15:52

Python 2 , 91 Bytes

a=b=1
t=0
for c in input():t=1+t*1j**(a*c*(a*a-c*c)*b**5%7*2/3+2*(a==c));a,b=b,c
print t==0

Probieren Sie es online aus!

Die Idee ist, jedes Triplett aufeinanderfolgender Würfelflächen, die gezeigt werden, in die entsprechende Windung zu übersetzen, die durch den Würfelweg gemacht wird. Die möglichen Drehrichtungen sind links, rechts, gerade oder umgekehrt, alle relativ zur vorherigen Bewegung des Würfels. Aus der Abfolge der Windungen verfolgen wir die aktuelle Koordinate des Würfels und prüfen, ob er zum Ursprung zurückkehrt. Anstatt die Blickrichtung des Würfels zu verfolgen, drehen wir einfach das gesamte Koordinatensystem um ihn herum, wenn es sich dreht, und bewegen es dann.

Auf diese Weise müssen wir den Zustand des Chips nicht selbst verfolgen - es reicht aus, nur lokale Schnipsel der Eingabesequenz zu betrachten. Wir verwenden auch keine fest codierten Werte oder magischen Zahlen.

Das schwierige Bit ist das Extrahieren der Drehrichtung aus den drei aufeinanderfolgenden Matrizenflächen. Sie können sich diese als einen Fehler vorstellen, der von der ersten zur zweiten Seite und dann von der zweiten zur dritten Seite kriecht - in welche Richtung muss die zweite Seite eingeschaltet werden, um dies zu tun? Wir können feststellen, dass es sich verdoppelt, wenn die erste und dritte Seite gleich sind, und dass es geradeaus geht, wenn die erste und dritte Seite gegenüberliegen, also addieren sie sich zu 7.

In den verbleibenden Fällen bleibt zu erkennen, ob sich der Fehler von links nach rechts dreht, dh das Dreifache der Gesichter ist linkshändig oder rechtshändig. Dazu leihen wir uns einen algebraischen Trick aus meiner CW-Lösung aus, um den Würfelwert aus der Seitenansicht zu bestimmen . Der Ausdruck 3*a*c*(a*a-c*c)ist entweder gleich boder -bmodulo 7, je nachdem, ob das Tripel Rechts- oder Linkshänder ist. Von dort führt eine Massage die vier Fälle von Drehrichtungen zu Zahlen, die 0,1,2,3Modulo 4 entsprechen, so dass wir mit dem komplexen Exponenten die richtige komplexe Drehung erhalten können 1j**.

5 JonathanAllan Sep 24 2020 at 05:30

Gelee , 35 Bytes

6RW;⁸œ?@\ḊḢ€⁼
“§ṫ²G‘×J$ṗLçƇ:19Ḣı*S¬

Ein monadischer Link, der den Würfelpfad als Liste der Gesichter in \ $ [1,6] \ $1 akzeptiert, was (wahrheitsgemäß) ergibt, wenn er wieder am Anfang endet, oder 0(falsey) auf andere Weise.

Probieren Sie es online aus! Oder sehen Sie sich die Testsuite an (6 am längsten entfernt, da die Methode ineffizient ist).

Wie?

Bildet alle möglichen Pfade der gegebenen Würfelpfadlänge, die aus den vier möglichen Richtungen als Permutationsindizes des nächsten Zustands gebildet werden.
Filtert diese, um diejenige zu finden, die den offenen Zahlen im angegebenen Würfelpfad entspricht.
Übersetzt die Permutationsindizes als komplexe Zahlen in die vier kartesischen Richtungen.
Überprüft, ob die Summe davon Null ist.

“§ṫ²G‘×J$ṗLçƇ:19Ḣı*S¬ - Main Link: dice-path
“§ṫ²G‘                - list of code-page indices = [225,245,130,71]
      ×J$             - multiply by their indices = [225,490,390,284]
                        (these correspond to [up, down, right, left])
          L           - length (of the dice-path)
         ṗ            - Cartesian power (all lists of that length using {225,490,390,284})
            Ƈ         - filter keep those for which:
           ç          -   call Link 1 as a dyad - f(potential-path, dice-path)
             :19      - integer divide by 19 (225,490,390,284 -> 11,25,20,14)
                Ḣ     - head (get the single path that filering found)
                        (having Ḣ here rather than before the :19 saves a byte)
                 ı*   - i exponentiate (that) (11,25,20,14 -> -i,i,1,-1)
                        (yep we've mirrored but it makes no difference)
                   S  - sum
                    ¬ - logical NOT

6RW;⁸œ?@\ḊḢ€⁼ - Link 1: potential-path (as permutation indices), dice-path
6             - six
 R            - range -> [1,2,3,4,5,6]
  W           - wrap -> [[1,2,3,4,5,6]]
   ;⁸         - concatenate with the permutation indices -> [[1,2,3,4,5,6],a,b,c,...]
        \     - cumulative reduce (current-state, permuation index) by:
       @      -   with swapped arguments:
     œ?       -     permuation (of the current state) at index (permutation index)
         Ḋ    - dequeue (remove the leading [1,2,3,4,5,6])
          Ḣ€  - head of each (get the list of face-up pips)
            ⁼ - equals (the dice-path)?
4 Noodle9 Sep 23 2020 at 20:26

Python 3 , 174 \$\cdots\$ 130 129 Bytes

Dank des Mannes Arnauld satte 15 30 35 Bytes gespart !!! Weitere satte 3 9 10 Bytes dank ovs gespeichert !!!

def f(l,p=[3,2,4,5,1,6],v=0):
 for d in l:n=p.index(d);v+=1j**n;p=[p[int(i)]for i in'%06d'%ord('񽣾첽񥙘꘣'[n])]
 return v==0

Probieren Sie es online aus!

Gibt zurück, Truewenn wir wieder am Ursprung oder auf Falseandere Weise landen .

Hafen von Neil ‚s Charcoal Antwort mit komplexer Arithmetik , wenn wir zurück , um herauszufinden , wo wir angefangen hat .

4 DominicvanEssen Sep 24 2020 at 21:25

R , 143 ... 116 102 Bytes

Bearbeitungen: -13 Bytes durch Umschalten auf linear anstelle der Matrixliste der Übergänge, dann -4 Bytes durch Halbieren der Liste der Übergänge und Berechnen der linken, hinteren und unteren Würfelwerte als 7 minus der rechten, vorderen und oberen Werte bei jedem Wurf. dann -3 Bytes durch Umschalten auf eine Basis-7-codierte Zahl, um die Liste der Übergänge zu erzeugen, dann -14 Bytes durch Umordnen der Übergangsliste nach oben, rechts, unten, links, um die Berechnung der neuen Position mit Potenzen von i, zu vereinfachen. und -6 Bytes von verschiedenen anderen kleinen Golfplätzen, die den Ansatz nicht verändert haben

p=a=1:4;m=5032105982%/%7^(11:0)%%7;for(i in scan()){p[6:4]=7-p;p=p[m[q<-(p[m[a]]==i)]];F=F+1i^a[q]};!F

Probieren Sie es online aus!

Wie?

(kommentierter Code vor dem Golfen)

is_dice_loop=
function(s,                     # s = vector of top die values along path
 p=1:6,                         # p = positions of current die values
                                #     (top,front,right,left,back,bot)
 m=matrix(                      # m = matrix of transitions at each roll
  utf8ToInt(                    #     created from ASCII values of
   "bedcfabbccafddfaafeeebcd")  #     this string
   -96,                         #     -96,
  4)                            #     matrix has 4 rows.
 ){
 for(i in s){                   # Now, for each die value i along the path
  r=match(i,p[m[,1]]);          #  calculate the roll direction r
                                #  (1:4 -> up,down,right,left),
  p=p[m[r,]];                   #  then calculate the new positions of die values,
  F=F+(-.5+r%%2)*1i^(r>2)       #  and calculate the new location of the die
                                #  as a complex number (real=left->right, imaginary=down->up)
                                #  (F is initialized as 0+0i by default).
 }
 !F                             # If we end up back at 0+0i, then we've done a loop,
}                               # so NOT F is true.  
4 att Sep 25 2020 at 04:16

Wolfram Language (Mathematica) , 96 91 83 74 Bytes

<<Quaternions`
0==Tr[a={-1,-K,J,-J,K,1};(a=#**a**#/2;#-1)&[1+a[[#]]]&/@#]&

Probieren Sie es online aus!

Quaternions` muss vor der Funktionsdefinition geladen werden.

<<Quaternions`          (* load the Quaternions` package *)
a={-1,-K,J,-J,K,1};     (* (a die roll of i moves the die in direction a[[i]]) *)
(a=#**a**#/2;#-1)&      (* rotate `a` in a direction, returning the direction, *)
% [1+a[[#]]]&/@#        (* taking directions one at a time from input. *)
0==Tr[ % ]&             (* check if sum of those directions returns to the origin. *)
2 NahuelFouilleul Sep 30 2020 at 03:05

Perl 5 -pF , 130 , 121 Bytes

@A=(2,4,-1,1,-@F,@F+!s/^/1/);s/.(?=.(.))/$x+=$A[$&==$1||$&+$1!=7&&($P[$|--]=$&)&&$1==$P[$|]?$A[$|]^=1:$A[$|]]/ge;$_=$x==1

Probieren Sie es online aus!

Eine andere Lösung, die einfache, war 173 Bytes , die auf 165 Bytes golfen konnten .

EDIT: Ich erkannte danach, dass die einfache auf 136 Bytes Golf gespielt werden konnte

Aber um mehr Golf zu spielen, denke ich anders. Verwenden Sie die Tatsache, dass die Summe der gegenüberliegenden Seite 7 ist. Und dass es ausreichen könnte, eine vorherige Zahl zu verfolgen, um die Anweisungen zu erhalten.

  • Array A:
    • [0]= {2 | 3} und [1]= {4 | 5}: Speichern der Richtung auf (+/-) x oder (+/-) y, wobei x und y von der Richtung der ersten Bewegung auf diesen Achsen abhängen
    • das nächste [2..5]: um Zahlen zu speichern, die $xder Richtung hinzugefügt werden sollen
  • s/^/1/: Stellen Sie 1das ursprüngliche Gesicht voran
  • Regex .(?=.(.)): Verbraucht ein Würfelgesicht $&und erfasst das nächste$1
  • $&==$1 Die Richtung ändert sich rückwärts
  • $&+$1==7 Die Richtung ändert sich nicht, der Test wird invertiert, weil nichts zu tun ist
  • Andernfalls hat sich die Richtung im Vergleich zur vorherigen Richtung nach rechts oder links geändert
  • Array P: speichert die letzte Würfelfläche [0] x, [1] y, wobei x und y von den ersten Zügen abhängen
    • $P[$|--]=$& ::
      • $P[$|]=$& zum Speichern der Matrizenfläche beim Drehen nach links oder rechts
      • $|-- schaltet den Achsindex 0/1 für x / y
  • $1==$P[$|] Die nächste nächste Fläche wird mit der letzten verglichen, wenn Sie sich auf derselben Achse bewegen, wenn sie gleich ist. Die Richtung ändert sich im Vergleich zur vorherigen Richtung rückwärts
  • ^=1 : Umschalten mit bytwise xor (2 <-> 3) oder (4 <-> 5)
  • $_=$x==1: Die Ausgangsposition, wenn der $x==1erste Zug (Richtung 2: -1) nicht hinzugefügt wurde.