Ihr Ziel ist es, einen perfekten Spieler für das Spiel Wythoffs Nim zu schreiben .
Regeln von Wythoffs Nim
Wythoffs Nim ist ein deterministisches Zwei-Spieler-Spiel, das mit zwei Stapeln identischer Spielsteine gespielt wird. Die Spieler wechseln sich ab, indem sie eine der folgenden Aktionen ausführen:
- Entfernen Sie eine oder mehrere Marken vom ersten Stapel
- Entfernen Sie eine oder mehrere Marken vom zweiten Stapel
- Entfernen Sie eine gleiche Anzahl von Zählmarken (eine oder mehrere) sowohl vom ersten als auch vom zweiten Stapel.
Natürlich können Stapel nicht negativ werden, aber sie können auf 0 gesetzt werden. Derjenige Spieler, der den letzten Zähler insgesamt entfernt, gewinnt das Spiel.
Für die Geometrischeren ist hier eine äquivalente Formulierung des Spiels, das Sie auf diesem Applet spielen können . Eine einzelne Dame beginnt auf einem Feld eines viertel-unendlichen Schachbretts, dessen Ecke sich unten links befindet. Die Spieler ziehen abwechselnd die Dame, die sich wie eine Schachkönigin bewegt, jedoch auf drei Richtungen beschränkt ist:
- Nieder
- Links
- Diagonal nach unten und links
Wer die Dame in die Ecke zieht, gewinnt.
Wenn Sie die Koordinaten der Dame (mit Ecke (0,0)
) mit den Größen der jeweiligen Stapel verknüpfen, können Sie leicht erkennen, dass beide Spiele gleich sind.
Perfektes Spiel
(Sie können dies überspringen, wenn Sie mit den Vorstellungen von perfektem Spiel und Gewinnzügen vertraut sind.)
Da Wythoffs Nim ein endliches und deterministisches Spiel ist, hat es eine Vorstellung von perfektem Spiel . Ein perfekter Spieler ist eine Strategie, die immer von einer theoretisch gewonnenen Position gewinnt, dh von einer Position, in der es eine Strategie gibt, die einen Sieg garantiert.
Um eine Gewinnstrategie zu sein, genügt es, sich immer auf eine theoretische Gewinnposition für den Spieler zu bewegen, der gerade umgezogen ist, und damit für den Spieler, der nicht weiter geht. Die ersten dieser Gewinnpositionen (auch als kalte Positionen bezeichnet ) sind (0,0), (1,2), (2,1), (3,5), (5,3)
. Im Wikipedia-Artikel finden Sie eine Erklärung eines Algorithmus zur Ermittlung einer Gewinnstrategie für Wythoffs Nim sowie eine Formel zur Generierung von Gewinnpositionen.
Programmanforderungen
Schreiben eines Programms oder einer Funktion nimmt eine Position als Eingabe ein und gibt einen Gewinnzug in Form der Position nach diesem Zug aus. Wenigste Bytes gewinnt.
Wenn kein Gewinnzug existiert, dh die Position ein theoretischer Verlust ist, sollte Ihr Programm dies anzeigen und verfallen.
Ihr Programm muss innerhalb eines angemessenen Zeitraums ausgeführt werden. Eine exponentielle rekursive Spielbaumsuche reicht also nicht aus. Wenn Sie eine Strategie vorberechnen und hart codieren möchten, ist das in Ordnung.
Eingang
Ein Paar (i,j)
nicht negativer Zahlen, die jeweils höchstens die Stapelgröße darstellen 99
. Dies können zwei Zahlen, ein Tupel, eine Liste oder ein beliebiger Container sein.
Ausgabe
Drucken oder geben Sie die Position nach Ihrem Umzug erneut als zwei Zahlen oder einen Container davon aus. Dies muss ein legaler Schritt zu einer Gewinnerposition sein. Wenn es mehrere solcher Züge gibt, ist jeder in Ordnung, aber nur einer.
Wenn es keinen Gewinnzug gibt, müssen Sie dies in der Ausgabe angeben. Jede Ausgabe wie False
, None
, 0, oder (-1,-1)
tun wird, solange es keine rechtliche Position ist, und ist für jeden Verlierer Eingang.
Beispiel läuft
f(5,0) = (0,0)
f(2,2) = (1,2) # Or (2,1) or (0,0)
f(1,2) = False
f(13,9) = (13,8) # Or (10,6)
f(10,6) = False
f(5,10) = (5,3)
f(25,30) = (8,13)
quelle
Antworten:
Haskell,
167165 ZeichenDer Algorithmus ist ineffizient, läuft jedoch innerhalb einer Sekunde (jedoch nicht in der interaktiven Konsole) für Eingaben <100.
Erläuterung:
Die Liste der kalten Positionen bei einer Reihe von vorherigen kalten Positionen ist eine kalte Position, gefolgt von der Liste der kalten Positionen bei dieser Position und den vorherigen Positionen (Ineffizienz: Diese Position wird zweimal generiert).
Eine kalte Position ist das erste Paar, sodass von diesem Paar keine kalten Positionen erreichbar sind. (Ineffizienz: Wir sollten stattdessen nach dem vorherigen Paar suchen.)
Von einem Paar aus erreichbare Positionen sind solche, bei denen die ersten Elemente, die zweiten Elemente, die Differenz oder der kleinere Haufen vor dem Entfernen mit dem größeren Haufen nach dem Entfernen übereinstimmen.
(Hauptmethode) Wenn sich die Haufen in der falschen Reihenfolge befinden, tauschen Sie sie aus. Wenn die erste kalte Position, die von einer Position aus erreichbar ist, die Position selbst ist, geben Sie einen Fehler an (im Idealfall würde man
Maybe (Int,Int)
stattdessen zurückkehren). Anderenfalls kehre diese kalte Position zurück (Ineffizienz: das Paar wird zweimal nachgeschlagen. Schlimmer noch, die Liste der kalten Positionen wird zweimal generiert).quelle
x@
fromx@(a,b)?p=...
GolfScript (
6357 Bytes)Erwartet die Eingabe von stdin im Formular
[a b]
und belässt die Ausgabe auf stdout in diesem Formular oder0
wenn es sich um eine Verlustposition handelt. Online-DemoÜberblick
berechnet eine Liste der kalten Positionen (einschließlich der gespiegelten Version
[b a]
für jede kalte Position[a b]
) unter Verwendung der Beatty-Sequenzeigenschaft .Dann
?
sucht nach der ersten Kaltstellung erfüllt den Block erstellt vonDabei wird im Wesentlichen überprüft, ob die Position von der Eingabeposition aus erreichbar ist, indem die Vektordifferenz berechnet und anschließend überprüft wird, ob dies entweder oder für einige der Fälle der Fall
[0 x]
ist . IMO , dass Test ist die geschickteste Bit: Kräfte jede Anordnung in einem dieser Formate in die Form während Zuordnung zu , wo weder noch ist an ein Array mit drei Elementen, und oder zu . Dann prüft, ob wir haben .[x 0]
[x x]
x > 0
0|$
[0 x]
[0 0]
[0]
[a b]
a
b
0
[-x 0]
[-x -x]
[-x 0]
(!*,1=
[0 x]
Zum Schluss
0]0=`
wird der Fallback-Fall und die Formatierung für die Ausgabe ausgeführt.quelle
Pyth 57
58 61 62Probieren Sie es online aus.
Ziemlich ähnlich zu anderen Antworten, aber diese Wikipedia-Seite hat nicht viel anderes zu bieten;) Die magische Zahl
39
ist die Anzahl der kalten Positionen mit Werten <99
.Definiert eine Funktion
g
, die Sie gerne aufrufen könneng 30 25
. Kehrt[]
bei[(13,8)]
Erfolg als Fehler zurück .Erläuterung
quelle
s
wird in int umgewandelt - speichert ein paar Zeichen/____1
.rZ39
kann durchU39
unären Bereich ersetzt werden. Ebenso können Sie ersetzenr99)
mitU99
.U
. Ich sollte die Erklärung wirklich aktualisieren: P@
wenn das zweite Argument jetzt eine Liste ist. Es ist ein bisschena
Javascript ES6 - 280 Bytes
Minimiert
Erweitert
Netter und schneller Algorithmus. Läuft in O (n), aber ohne eine bytesparende Schleife in konstanter Zeit. Die Schleife ist als rekursiver Inkrementierer implementiert, daher schlägt das Skript möglicherweise mit einem Rekursionsfehler für n in den Hunderten oder Tausenden fehl . Verwendet die gleiche Beatty-Sequenzeigenschaft wie Mr. Taylor, aber anstatt die Sequenz zu berechnen, wird einfach zu den richtigen Begriffen gesprungen.
Läuft einwandfrei auf allen Testeingängen und vielen Dutzenden davon, die ich getestet habe.
Die aufzurufende Funktion ist
f
. Es gibt ein Array bei Erfolg und0
bei Aufgeben zurück.quelle
Perl 5 - 109 (mit 2 Flags)
Verwendung:
Berechnet einfach die Lösung für jede mögliche Eingabe und führt dann eine einzelne Suche durch.
quelle