Überprüfen Sie, ob das 15-Puzzle lösbar ist


9

Das fünfzehn Rätsel ist insofern eigenartig, als nur die Hälfte der möglichen Anordnungszustände lösbar sind. Wenn Sie die Kacheln 14 und 15 umdrehen, können Sie die Blöcke auf keinen Fall so verschieben, dass sie zurückgedreht werden.

Ihre Aufgabe besteht darin, ein Programm zu erstellen, das eine Liste von Ganzzahlen im Format Ihrer Wahl akzeptiert (die genau eine Instanz jeder der Zahlen von 0 bis 15 enthält, wobei 0 das Leerzeichen ist), die den Status einer Anordnung von Kacheln in darstellt ein 4x4-Gitter und gibt einen einzelnen booleschen Wert aus, der bestimmt, ob das Gitter lösbar ist oder nicht.

Der kürzeste Code dafür in einer Sprache gewinnt.


Gute Frage :)
Cruncher

Ich wollte diese Frage stellen, aber mit einer willkürlichen Seitenlänge; Aber das trägt sehr wenig zur Herausforderung bei.
Jonathan Allan

Antworten:


0

Gelee , 9 Bytes

Œc>/€;TSḂ

Ein monadischer Link, der eine Liste der Ganzzahlen akzeptiert, die in Zeilen-Hauptreihenfolge abwechselnd zwischen links-rechts und rechts-links gelesen werden. Dies ergibt, 0wenn lösbar und 1wenn nicht (um dies zu invertieren ¬, rechts neben dem Code hinzufügen ).

Probieren Sie es online aus! (Dieses Beispiel ist eine Tafel, auf der 12 nur einrasten muss.)

Wie?

Ähnlich wie bei John Dvoraks Antwort berechnen wir Paritäten und verwenden eine schlangenartige Eingabereihenfolge, um die Schachbrettparität zu vereinfachen. Statt jedoch die Gleichheit der Parität zu überprüfen, addieren wir die Anzahl der nicht in der Reihenfolge befindlichen Werte mit den Nicht-Null-Indizes und testen, ob dies der Fall ist seltsam:

Œc>/€;TSḂ - Link: list of integers
Œc        - unordered pairs
    €     - for each:
   /      -   reduce with:
  >       -     greater than?
      T   - truthy indices (i.e. [1..16] without 1-indexed index of 0)
     ;    - concatenate
       S  - sum
        Ḃ - is odd?

4

J, 28 Zeichen

((C.!.2=_1^i.&0)&.".&.stdin''

Die Eingabereihenfolge ist zeilenweise, wobei die Zeilen abwechselnd von links nach rechts und von rechts nach links in einem einzelnen Pfad über die Tabelle gelesen werden. Angenommen, die Null gehört zur oberen linken Ecke.

Verwendung unter Windows:

<nul set /p="0 1 2 3 7 6 5 4 8 9 10 11 15 14 13 12" | jconsole c:\...\15.jhs

Erläuterung:

  • <nul set /p=wird verwendet, um eine neue Zeile in der Eingabe zu verhindern, die echoerzeugt, ".die nicht gefällt. Natürlich unterstützt Unix echo /n.
  • v&.".&.stdin''liest "v unter Analyse unter stdin" und bedeutet "Eingabe, dann Analyse der Eingabe, dann v, dann Rückgängig machen der Analyse (= Format), dann Rückgängig machen der Eingabe (= Ausgabe)". 1!:1]3ist ein Zeichen kürzer, hat aber keine definierte Umkehrung.
  • C.!.2bedeutet "Permutationsparität". Es wird entweder 1(gerade Parität) oder _1(ungerade Parität) zurückgegeben. Das ist,_1^inversions
  • _1^i.&0 bedeutet "-1 hoch dem Index von 0".
  • Somit C.!.2=_1^i.&0bedeutet „funktioniert die Permutation Parität , die Lochposition Parität gleich?“

Dies funktioniert für eine 4x4-Karte, aber wenn die gewünschte Endposition von links nach rechts zeilenweise ist, hat die Permutation für die gelöste Position eine ungerade Anzahl von Inversionen und damit eine ungerade Parität. Außerdem wird die Parität umgekehrt (für jede Eingabereihenfolge), wenn sich die gewünschte Lochposition von links oben nach rechts unten bewegt. In beiden Fällen ist das Update ein Zeichen: add -nach =der erwarteten Parität zu umkehren.

Korrektheitsnachweis:

Nach jeder Bewegung tauscht die Null eine Position mit einer bestimmten Zahl aus, wodurch die Permutationsparität umgedreht wird. Die Null wechselt auch zwischen weißen und schwarzen Schachbrettpositionen, die durch ungerade und gerade Positionen in der Eingabereihenfolge angezeigt werden. Somit ist diese Bedingung notwendig. Das Zählargument reicht auch aus: Es ist allgemein bekannt, dass genau die Hälfte der Positionen lösbar ist. Dieser Zustand filtert genau die Hälfte der möglichen Positionen heraus.


Wenn Sie sagen "Die Null wechselt auch zwischen ungeraden und geraden Positionen": Ändert sie sich nicht um +1, -1, +4 oder -4? Ich denke, dass ein kariertes Muster die Farbe ergibt, die Sie benötigen, aber es könnte genauer beschrieben werden.
Peter Taylor

@ PeterTaylor du hast recht; Es tut uns leid. Zählt meine Bearbeitung als gültiger Fix?
John Dvorak

Ich denke, Ihre Bearbeitung befasst sich mit einem völlig anderen Problem. Das Bit, das ich zitiert habe, ist im letzten Absatz.
Peter Taylor

"Zwischen ungeraden und geraden Positionen" ist eher wie "zwischen schwarzen und weißen Quadraten auf einem Schachbrett".
Joe Z.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.