Hilfe, ich bin in einem Sierpinski-Dreieck gefangen!

44

Das Zeichnen des Sierpinski-Dreiecks wurde zu Tode gebracht . Es gibt aber noch andere interessante Dinge, die wir damit machen können. Wenn wir stark genug auf das Dreieck blinzeln, können wir umgedrehte Dreiecke als Knoten eines fraktalen Graphen anzeigen. Lassen Sie uns unseren Weg durch diese Grafik finden!

Weisen wir zunächst jedem Knoten eine Nummer zu. Das größte umgedrehte Dreieck ist der Knoten Null, und dann gehen wir Schicht für Schicht (Breite zuerst) nach unten und weisen fortlaufende Nummern in der Reihenfolge oben links rechts zu:

Bildbeschreibung hier eingeben
Klicken Sie für eine größere Version, bei der die kleinen Zahlen etwas weniger verschwommen sind.

(Natürlich wird dieses Muster fortgesetzt ad infinitum im blauen Dreiecke.) Eine weitere Möglichkeit , die Nummerierung zu definieren , ist , dass der Mittelpunkt Knotenindex hat 0, und die Kinder des Knotens i(benachbarte Dreiecken des nächsten kleineren Maßstabs) haben Indizes 3i+1, 3i+2und 3i+3.

Wie bewegen wir uns in dieser Grafik? Es gibt bis zu sechs natürliche Schritte, die von einem bestimmten Dreieck ausgeführt werden können:

  • Man kann sich immer durch den Mittelpunkt einer der Kanten zu einem der drei untergeordneten Knoten des aktuellen Knotens bewegen. Wir werden diese Bewegungen als bezeichnen N, SWund SE. Zum Beispiel , wenn wir zur Zeit auf dem Knoten sind 2, würden diese zu Knoten führen 7, 8, 9, respectively. Andere Bewegungen durch die Kanten (zu indirekten Nachkommen) sind nicht zulässig.
  • Man kann sich auch durch eine der drei Ecken bewegen, vorausgesetzt, sie berührt nicht den Rand des Dreiecks, entweder zu dem direkten Elternteil oder zu einem von zwei indirekten Vorfahren. Wir werden diese Bewegungen als bezeichnen S, NEund NW. Wenn wir uns gerade auf dem Knoten befinden 31, Swürde dies zu 10, NEwäre ungültig und NWwürde zu führen 0.

Die Herausforderung

Geben Sie zwei nicht negative ganze Zahlen ein xund yfinden Sie den kürzesten Weg von xnach y, indem Sie nur die oben beschriebenen sechs Züge verwenden. Wenn es mehrere kürzeste Pfade gibt, geben Sie einen davon aus.

Beachten Sie, dass Ihr Code für mehr als nur die in der obigen Abbildung gezeigten 5 Ebenen funktionieren sollte. Sie können das annehmen x, y < 1743392200. Dadurch wird sichergestellt, dass sie in eine 32-Bit-Ganzzahl mit Vorzeichen passen. Beachten Sie, dass dies 20 Ebenen des Baums entspricht.

Ihr Code muss alle gültigen Eingaben in weniger als 5 Sekunden verarbeiten . Während dies eine Brute-Force-Breitensuche ausschließt, sollte es eine ziemlich lockere Einschränkung sein - meine Referenzimplementierung verarbeitet willkürliche Eingaben für die Tiefe 1000 in einer halben Sekunde (das sind ~ 480-stellige Zahlen für die Knoten).

Sie können ein Programm oder eine Funktion schreiben, indem Sie eine Eingabe über STDIN (oder die nächstgelegene Alternative), ein Befehlszeilenargument oder ein Funktionsargument vornehmen und das Ergebnis über STDOUT (oder die nächstgelegene Alternative), einen Funktionsrückgabewert oder einen Funktionsparameter (out) ausgeben.

Die Ausgabe sollte eine flache, eindeutige Liste der Saiten sein N, S, NE, NW, SE, SW, unter Verwendung eines beliebigen angemessenen Separators (Leerzeichen, Zeilenumbrüche, Kommas, ","...).

Es gelten die Standardregeln für .

Testfälle

Die ersten Testfälle können anhand des obigen Diagramms von Hand herausgearbeitet werden. Die anderen sorgen dafür, dass die Antworten ausreichend effizient sind. Für diese gibt es möglicherweise andere Lösungen mit der gleichen Länge, die nicht aufgeführt sind.

0 40                    => N N N N
66 67                   => S SW N N N
30 2                    => NW NW -or- NE SW
93 2                    => NE SW
120 61                  => NW NW NW NW N SE SW N
1493682877 0            => S S NW NW
0 368460408             => SW SW N N SW SW SE SW SW N SE N N SW SW N SE SE
1371432130 1242824      => NW NW NE NW N SE SW SW SW SE SE SW N N N N SW
520174 1675046339       => NE NW NE NE SE SE SW SW N SE N SW N SW SE N N N N SE SE SW SW
312602548 940907702     => NE NW S SW N N SW SE SE SE SW SE N N SW SE SE SE SW
1238153746 1371016873   => NE NE NE SE N N SW N N SW N SE SE SW N SW N N SE N SE N
547211529 1386725128    => S S S NE NW N N SE N SW N SE SW SE SW N SE SE N SE SW SW N
1162261466 1743392199   => NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE
Martin Ender
quelle

Antworten:

5

Ruby, 195 194 190 184 Bytes

Original: Mit Entschuldigungen an Ell , da dies im Wesentlichen ein Teil ihrer Antwort ist, und vielen Dank an Doorknob für ihre Hilfe beim Debuggen dieser Antwort. Es gibt wahrscheinlich einen anderen Algorithmus für dieses Problem - etwas, das damit zu tun hat *f[x[0,**however far x matches with y**],y]- aber ich werde das für ein anderes Mal speichern.

a=->n{n<1?[]:a[~-n/3]+[-n%3]}
f=->x,y{j=x.size
(Array===x)?x==y[0,j]?y[j..-1].map{|m|%w[SE SW N][m]}:x.uniq.map{|m|[%w[NW NE S][m],*f[x[0,x.rindex(m)],y]]}.min_by(&:size):f[a[x],a[y]]}

EDIT: Der Greedy-Algorithmus funktioniert nicht für h[299792458, 1000000]. Ich habe die Byteanzahl auf 195 zurückgesetzt, während ich meinen Algorithmus erneut repariere. Es wurde nur behoben, dass die Byteanzahl auf 203 stieg. Seufz

Im Aufbau: Dieses Programm verwendet einen gierigen Algorithmus, um gemeinsame Vorfahren zu finden x[0,j]==y[0,j](Hinweis: Es können mehrere gemeinsame Vorfahren vorhanden sein). Der Algorithmus basiert sehr locker auf Ell 's rekursiver Ahnenrecherche. In der ersten Hälfte der resultierenden Anweisungen wird beschrieben, wie Sie zu diesem gemeinsamen Vorfahren gelangen, und in der zweiten Hälfte, wie Sie zu y gelangen, basierend auf y[j..-1].

Hinweis: a[n]Hier wird eine bijektive Basis-3- Nummerierung unter Verwendung der Ziffern 2,1,0anstelle von zurückgegeben 1,2,3.

Lassen Sie uns als Beispiel f[59,17]oder durchgehen f[[2,0,2,1],[2,1,1]]. Hier j == 1. Um dorthin zu gelangen x[0,j], gehen wir 0oder NW. Dann, um zu kommen y, zu gehen [1,1]oderSW SW

a=->n{n<1?[]:a[~-n/3]+[-n%3]}
h=->m,n{x=a[m];y=a[n];c=[];j=x.size
(j=x.uniq.map{|m|k=x.rindex(m);x[0..k]==y[0..k]?j:k}.min
c<<%w[NW NE S][x[j]];x=x[0,j])until x==y[0,j]
c+y[j..-1].map{|m|%w[SE SW N][m]}}
Sherlock9
quelle
45

Python 2, 208 205 200 Bytes

A=lambda n:n and A(~-n/3)+[-n%3]or[]
f=lambda x,y:f(A(x),A(y))if x<[]else["SSNEW"[m::3]for m in
y[len(x):]]if x==y[:len(x)]else min([["NNSWE"[m::3]]+f(x[:~x[::-1].index(m)],y)for
m in set(x)],key=len)

Eine Funktion, fdie ein Paar von Knotennummern verwendet und den kürzesten Pfad als Liste von Zeichenfolgen zurückgibt.

Erläuterung

Wir beginnen mit einem anderen Adressierungsschema für die Dreiecke. Die Adresse jedes Dreiecks ist eine Zeichenfolge, die wie folgt definiert ist:

  • Die Adresse des zentralen Dreiecks ist die leere Zeichenfolge.

  • Die Adressen des Nord, Süd-West und Süd-Ost - Kinder jeden Dreieck sind Anfügen gebildet 0, 1und 2jeweils an die Adresse des Dreiecks.

Im Wesentlichen codiert die Adresse jedes Dreiecks den (kürzesten) Pfad vom zentralen Dreieck zu ihm. Als erstes übersetzt unser Programm die eingegebenen Dreiecksnummern in die entsprechenden Adressen.

Abbildung 1

Klicken Sie auf das Bild für eine größere Version.

Die möglichen Bewegungen an jedem Dreieck lassen sich leicht anhand der Adresse ermitteln:

  • Um nach Norden zu bewegen, Süd-West und Süd-Ost - Kindern, wir einfach Anfügen 0, 1und 2jeweils an die Adresse.

  • Um nach Süden zu bewegen, im Nordosten und Nordwesten Vorfahren, finden wir das letzte (ganz rechts) Auftreten 0, 1und 2, bzw., und schneiden Sie die Adresse auf dem von ihr übrig. Wenn keine 0, 1oder 2in der Adresse vorhanden ist, ist der entsprechende Vorfahr nicht vorhanden. Wenn 112wir uns zum Beispiel zum nordwestlichen Vorfahren von (dh seinem Elternteil) bewegen , finden wir das letzte Vorkommen von 2in 112, das das letzte Zeichen ist, und schneiden die Adresse links davon ab, was uns ergibt 11. Um zu dem nordöstlichen Vorfahren zu gelangen, finden wir das letzte Vorkommen von 1in 112, das das zweite Zeichen ist, und schneiden die Adresse links davon ab, was uns ergibt 1. hat jedoch 112keinen südlichen vorfahren, da es keinen gibt0 in seiner Adresse.

Beachten Sie ein paar Dinge zu einem Adresspaar xund y:

  • Wenn xein Anfangssubstring von ist y, dann yist es ein Nachkomme von x, und daher folgt der kürzeste Weg von xnach yeinfach dem entsprechenden Kind jedes Dreiecks zwischen xund y; in anderen Worten, wir können jeden ersetzen 0, 1und 2in y[len(x):]mit N, SWund SE, respectively.

  • Ansonsten sei ider Index der ersten Nichtübereinstimmung zwischen xund y. Es gibt keinen Weg von xzu y, der nicht durchgeht x[:i](was dasselbe ist wie y[:i]), dh der erste gemeinsame Vorfahr von xund y. Daher von jedem Weg xzu ybei ankommen müssen x[:i], oder einer seiner Vorfahren, lassen Sie sich dieses Dreieck nennen z, und dann weiter zu y. Um von xnach zu gelangen z, folgen wir den oben beschriebenen Vorfahren. Der kürzeste Weg von zbis ywird durch den vorherigen Aufzählungspunkt angegeben.

Wenn xes sich um eine erste Teilzeichenfolge von handelt y, wird der kürzeste Pfad von xbis yleicht durch den ersten Aufzählungspunkt oben angegeben. Ansonsten lassen wir jdie kleinste der Indizes der letzten Vorkommen sein 0, 1und 2in x. Wenn jgrößer als oder gleich der Index der ersten Nichtübereinstimmung zwischen xund y, iwir der entsprechenden Bewegung einfach hinzuzufügen ( S, NE, oder NW, jeweils) auf den Pfad, trim xlinks von jund fortzusetzen. Schwieriger wird es, wenn jweniger ist als i, da wir dann möglicherweise am yschnellsten sind, indem wir x[:j]direkt zum gemeinsamen Vorfahren aufsteigen und bis dahin absteigeny, oder wir könnten in der Lage sein, zu einem anderen gemeinsamen Vorfahren von zu gelangen, xund ydas ist näher, yindem wir zu einem anderen Vorfahren von xrechts von aufsteigen iund von dort zu yschneller gelangen. Um beispielsweise von 1222nach zu gelangen , 1muss der kürzeste Weg zuerst zum zentralen Dreieck (dessen Adresse die leere Zeichenfolge ist) und dann nach unten verlaufen 1, dh der erste Zug führt uns links vom Punkt der Nichtübereinstimmung. Um jedoch von 1222nach zu gelangen , 12ist der kürzeste Weg der Aufstieg nach 122und dann nach 12, dh der erste Zug hält uns rechts vom Punkt der Nichtübereinstimmung.

Wie finden wir den kürzesten Weg? Das "offizielle" Programm verwendet einen Brute-Force-ish-Ansatz, bei dem alle möglichen Züge zu einem der Vorfahren versucht werden, wenn xes sich nicht um eine erste Teilzeichenfolge von handelt y. Es ist nicht so schlimm wie es klingt! Es löst alle Testfälle zusammen in ein oder zwei Sekunden.

Andererseits können wir viel besser: Wenn es mehr als einen direkt erreichbaren Vorfahren links vom Übereinstimmungspunkt gibt, müssen wir nur den ganz rechten testen, und wenn es mehr als einen direkt erreichbaren Vorfahren gibt Rechts vom Punkt der Nichtübereinstimmung müssen wir nur den am weitesten links stehenden testen. Dies ergibt einen linearen Zeitalgorithmus mit der Länge von x(dh der Tiefe des Quellendreiecks oder einer Zeit proportional zum Logarithmus der Quellendreieckzahl), der durch noch viel größere Testfälle zoomt. Das folgende Programm implementiert diesen Algorithmus zumindest im Wesentlichen - aufgrund des Golfspiels ist seine Komplexität zwar schlechter als linear, aber immer noch sehr schnell.

Python 2, 271 266 261 Bytes

def f(x,y):
 exec"g=f;f=[]\nwhile y:f=[-y%3]+f;y=~-y/3\ny=x;"*2;G=["SSNEW"[n::3]for
n in g];P=G+f;p=[];s=0
 while f[s:]:
    i=len(f)+~max(map(f[::-1].index,f[s:]));m=["NNSWE"[f[i]::3]]
    if f[:i]==g[:i]:P=min(p+m+G[i:],P,key=len);s=i+1
    else:p+=m;f=f[:i]
 return P

Beachten Sie, dass diese Version im Gegensatz zur kürzeren Version speziell dafür geschrieben wurde, bei der Konvertierung der Eingabewerte in die entsprechenden Adressen keine Rekursion zu verwenden, damit sehr große Werte verarbeitet werden können, ohne den Stapel zu überlaufen.

Ergebnisse

Das folgende Snippet kann verwendet werden, um die Tests für beide Versionen auszuführen und die Ergebnisse zu generieren:

def test(x, y, length):
    path = f(x, y)
    print "%10d %10d  =>  %2d: %s" % (x, y, len(path), " ".join(path))
    assert len(path) == length

#         x           y        Length
test(          0,          40,    4   )
test(         66,          67,    5   )
test(         30,           2,    2   )
test(         93,           2,    2   )
test(        120,          61,    8   )
test( 1493682877,           0,    4   )
test(          0,   368460408,   18   )
test( 1371432130,     1242824,   17   )
test(     520174,  1675046339,   23   )
test(  312602548,   940907702,   19   )
test( 1238153746,  1371016873,   22   )
test(  547211529,  1386725128,   23   )
test( 1162261466,  1743392199,   38   )

Golf Version

         0         40  =>   4: N N N N
        66         67  =>   5: S SW N N N
        30          2  =>   2: NE SW
        93          2  =>   2: NE SW
       120         61  =>   8: NW NW NW NW N SE SW N
1493682877          0  =>   4: S S NW NW
         0  368460408  =>  18: SW SW N N SW SW SE SW SW N SE N N SW SW N SE SE
1371432130    1242824  =>  17: NW NW NE NW N SE SW SW SW SE SE SW N N N N SW
    520174 1675046339  =>  23: NE NE NE NE SE SE SW SW N SE N SW N SW SE N N N N SE SE SW SW
 312602548  940907702  =>  19: NE NW S SW N N SW SE SE SE SW SE N N SW SE SE SE SW
1238153746 1371016873  =>  22: NE NE NE SE N N SW N N SW N SE SE SW N SW N N SE N SE N
 547211529 1386725128  =>  23: S S S S NW N N SE N SW N SE SW SE SW N SE SE N SE SW SW N
1162261466 1743392199  =>  38: NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE

Effiziente Version

         0         40  =>   4: N N N N
        66         67  =>   5: S SW N N N
        30          2  =>   2: NW NW
        93          2  =>   2: NE SW
       120         61  =>   8: NW NW NW NW N SE SW N
1493682877          0  =>   4: NE S NW NW
         0  368460408  =>  18: SW SW N N SW SW SE SW SW N SE N N SW SW N SE SE
1371432130    1242824  =>  17: NW NW NE NW N SE SW SW SW SE SE SW N N N N SW
    520174 1675046339  =>  23: NE NW NE NE SE SE SW SW N SE N SW N SW SE N N N N SE SE SW SW
 312602548  940907702  =>  19: NE NW S SW N N SW SE SE SE SW SE N N SW SE SE SE SW
1238153746 1371016873  =>  22: NE NE NE SE N N SW N N SW N SE SE SW N SW N N SE N SE N
 547211529 1386725128  =>  23: S S S S NW N N SE N SW N SE SW SE SW N SE SE N SE SW SW N
1162261466 1743392199  =>  38: NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE
Ell
quelle
6
Verdammt, das war schnell. Ich kann dir nicht sagen, wie glücklich es mich jedes Mal macht, wenn ich dich dazu bringe, eine meiner Herausforderungen zu beantworten. :)
Martin Ender
2
@ MartinBüttner Danke, das ist ein riesen Kompliment! FWIW, es macht mir großen Spaß, Ihre Herausforderungen zu lösen. Ich könnte oder könnte nicht begonnen haben, an diesem zu arbeiten, während es noch im Sandkasten war ... :)
Ell
2
Das Adressierungsschema ist genial. Das ist fantastisch.
BrainSteel
1
@BrainSteel Das erste, was mir einfiel, war, dieses Adressierungsschema auszuprobieren, aber zu sehen, wie das Ganze in weniger als einer Stunde konzipiert, implementiert und geschrieben wurde, ist fantastisch. +1
Level River St
1
@Zymus Ich bin nicht sicher, ob ich folge, aber wenn Sie sich auf das Bild beziehen, sollte es nicht mit dem OP übereinstimmen - dies ist ein anderes Adressierungsschema, wie im Beitrag beschrieben.
Ell
3

APL (Dyalog Unicode) , 144 132 129 118 133 132 130 124 117 Byte SBCS

Vielen Dank an Ven und ngn für ihre Hilfe beim Golfspielen in The APL Orchard , einem großartigen Ort, um die APL-Sprache zu lernen. ⎕IO←0. Golfvorschläge sind willkommen.

Edit: -12 Bytes dank Ven und ngn durch Änderung der nDefinition und Umstellung von 1-Indizierung auf 0-Indizierung. -3 aufgrund der Behebung eines Fehlers, bei dem nicht alles auf 0-Indizierung umgestellt wurde. -11 Bytes aufgrund von Änderungen in der Art Pund Weise der QDefinition. +15 Bytes, da ein Problem behoben wurde, bei dem mein Algorithmus nicht korrekt war. Vielen Dank an ngn für die Hilfe beim Ermitteln des s[⊃⍋|M-s]Abschnitts. -2 Bytes von der Neuordnung der Methode zum Auffinden des Backtracking-Pfades und +1 Byte bis zur Fehlerbehebung. -2 Bytes dank Adám von der Neuordnung der Definition von I. -6 Byte dank ngn aus der Neuordnung der Definition 'S' 'NE' 'NW' 'N' 'SW' 'SE'und aus der Neuordnung der tDefinition (es ist keine separate Variable mehr). -7 bytes dank ngn vom golf wie sdefiniert.

{M←⊃⍸≠⌿↑1+P Q←⍵{(⍵/3)⊤⍺-+/3*⍳⍵}¨⌊31+⍵×2⋄(∪¨↓6 2'SSNENWNNSWSE')[P[I],3+Q↓⍨⊃⌽I←⍬{M≥≢⍵:⍺⋄(⍺∘,∇↑∘⍵)s[⊃⍋|M-s←⌽⊢.⊢⌸⍵]}P]}

Probieren Sie es online!

Eine Erklärung des Fehlers im Algorithmus

Das Grundproblem ist, dass ich dachte, der kürzeste Weg würde direkt durch den gemeinsamen Vorfahren verlaufen und könnte tatsächlich nicht durch einen Vorfahren des gemeinsamen Vorfahren verlaufen. Dies ist nicht korrekt, wie die folgenden Beispiele zeigen.

Von 66 bis 5

66  0 2 2 2  0 2 2 2
5   0 1      0 1
       common ancestor

The two ancestors of 0 2 2 2 are:
0 2 2
(empty)

(empty) has the shorter path back to 0 1 as it only needs two forward moves,
while 0 2 2 requires two more backtracks and one more forward move.

Von 299792458 bis 45687

299792458  0 2 1 1 0 1 1 2 1 1 1 2 1 0 2 2 2 0
45687      0 2 1 1 0 1 1 1 2 2
                          common ancestor

The three ancestors of 299792458 are:
0 2 1 1 0 1 1 2 1 1 1 2 1 0 2 2 2
0 2 1 1 0 1 1 2 1 1 1 2             choose this one
0 2 1 1 0 1 1 2 1 1 1 2 1 0 2 2

And the three ancestors of 0 2 1 1 0 1 1 2 1 1 1 2 are:
0 2 1 1
0 2 1 1 0 1 1 2 1 1
0 2 1 1 0 1 1 2 1 1 1

0 2 1 1 0 1 1 1 2 2     45687 for reference
              common ancestor

While it seems like `0 2 1 1` is the shorter path,
it actually results in a path that is 8 steps long
(2 backtracks, 6 forward steps to 45687).

Meanwhile, `0 2 1 1 0 1 1 2 1 1` is at an equal distance
to the common ancestor and has the following ancestors:
0 2 1 1
0 2 1 1 0 1 1 2 1
0 2 1 1 0 1 1

0 2 1 1 0 1 1 1 2 2     45687 for reference
              common ancestor

Clearly, this is the superior path, as with three backtracks, we have reached
the point of the common ancestor. With 3 backtracks and 3 forward moves,
we have a path that is 6 steps long.

Erklärung des Codes

                         should be an array of 2 integers, x y
SierpinskiPath←{⎕IO0   0-indexing
         P Q←{...}¨⍵   First, the bijective base-3 numeration of x and y
    P Q←{
        n←⌊31+⍵×2   The number of digits in the numeration
        z←+/3*⍳⍵     The number of numerations with  n digits
        (n/3)⊤⍵-z    And a simple decode  (base conversion) of ⍵-z
    }¨⍵              gets us our numerations, our paths

    A←↑1+P Q       We turn (1+P Q) into an 2-by-longest-path-length array 
                    pads with 0s and our alphabet also uses 0s
                   So we add 1 first to avoid erroneous common ancestor matches
    Common←⊃⍸≠⌿A   We find the length of the common ancestor, Common

         I←⍬{...}P   Now we get the shortest backtracking path from P
    I←⍬{
        Common=≢⍵:⍺        If P is shorter than Common, return our backtrack path
        s←⌽⊢.⊢⌸⍵           Get the indices of the most recent N SW SE
        ts[⊃⍋|Common-s]   and keep the index that is closest to Common
                           and favoring the ancestors to the right of
                           Common in a tiebreaker (which is why we reverse ⊢.⊢⌸⍵)
        (⍺,t)∇t↑⍵          Then repeat this with each new index to backtrack
    }P                     and the path left to backtrack through

    BacktrackP[I]    We get our backtrack directions
    Forward←(⊃⌽I)↓Q   and our forward moves to Q
                      starting from the appropriate ancestor
    (∪¨↓6 2'SSNENWNNSWSE')[Backtrack,Forward]     'S' 'NE' 'NW' 'N' 'SW' 'SE'
}                     and return those directions

Alternative Lösung mit Dyalog Extended und dfns

Wenn wir verwenden ⎕CY 'dfns'‚s - adicFunktion implementiert er unsere bijective Basis-n numeration (die die Inspiration für die Version , die ich benutzt wurde) für weit weniger Bytes. Der Wechsel zu Dyalog Extended spart auch eine ganze Reihe von Bytes und so sind wir hier. Vielen Dank an Adám für seine Hilfe beim Golfspielen. Golfvorschläge willkommen!

Bearbeiten: -8 Bytes aufgrund einer Änderung, wie Pund Qdefiniert sind. -14 Bytes aufgrund der Umstellung auf Dyalog Extended. -2 aufgrund der Verwendung eines vollständigen Programms zum Entfernen der dfn-Klammern {}. +17 Bytes, da ein Problem behoben wurde, bei dem mein Algorithmus nicht korrekt war. Vielen Dank an ngn für die Hilfe beim Ermitteln des s[⊃⍋|M-s]Abschnitts. +1 Byte zur Fehlerbehebung. -2 Bytes dank Adám von der Neuordnung der Definition von I und -1 Bytes von der Erinnerung daran, meine Golfs in beide Lösungen zu stecken . -3 Bytes dank ngn durch Neuordnung der Generierung der Hauptrichtungen, +1 Byte durch Korrektur eines fehlerhaften Golfs und -3 Bytes dank ngn durch Neuordnung der tDefinition (es ist keine separate Variable mehr). -7 Bytes dank ngn durch Neuordnung wie sdefiniert.

APL (Dyalog Extended) , 123 115 101 99 116 117 114 109 102 Byte

M←⊃⍸≠⌿↑1+P Q←(⍳3)∘⌂adic¨⎕⋄(∪¨↓6 2'SSNENWNNSWSE')[P[I],3+Q↓⍨⊃⌽I←⍬{M≥≢⍵:⍺⋄(⍺∘,∇↑∘⍵){⍵[⊃⍋|M-⍵]}⌽⊢.⊢⌸⍵}P]

Probieren Sie es online!

Sherlock9
quelle
Für 66 und 1 findet dies nicht den kürzesten Weg über 0.
Christian Sievers
@ChristianSievers Du hast vollkommen recht und ich bin mir nicht sicher, wie ich das noch beheben soll. Danke für die Information.
Sherlock9