Chomp ist ein Zwei-Spieler-Spiel mit einem Aufbau aus einem Rechteck von Stücken. Jeder Spieler ist an der Reihe und entfernt ein beliebiges Teil sowie alle darüber und rechts davon befindlichen Teile. Wer das linke untere Stück nimmt, verliert. Es kann ziemlich leicht bewiesen werden, dass der erste Spieler immer einen Gewinnzug hat (außer bei einem 1-zu-1-Rechteck); finde es.
- Eingabe ist die Abmessung des Rechtecks (zwei Zahlen)
- Ausgabe ist der Ort des Gewinnzugs (zwei Zahlen)
- Wenn es mehr als einen Gewinnzug gibt, können Sie jeden davon ausgeben.
Das ist Code Golf; Der kürzeste Code (jede Sprache) gewinnt.
Beispiele
Hinweis: Die Ausgaben sind nur die beiden Zahlen; Die unten stehende ASCII-Grafik soll nur veranschaulichen, was die Zahlen bedeuten.
Eingabe: 5 3 (Indizes 1-basiert ab linker unterer Ecke)
Ausgabe: 4 3
XXX--
XXXXX
XXXXX
Eingabe: 4 4
Ausgang: 2 2
X---
X---
X---
XXXX
Bonus
Subtrahieren Sie 15 Zeichen von Ihrer Punktzahl, wenn Sie alle Gewinnzüge ausgegeben haben. Jedes Zahlenpaar muss durch eine neue Zeile getrennt werden.
Antworten:
GolfScript, 82 (
10897 Zeichen - 15 Bonus)Da ich keine Heuristik kannte, führt diese Lösung eine umfassende Suche im Lösungsraum durch. Sie können den Code online ausprobieren . Obwohl die Implementierung sehr effizient ist, wächst der Suchraum mit zunehmender Eingabe sehr schnell.
Beispiele:
Wie oben erwähnt, beruht die Implementierung nicht auf Rekursion, sondern besucht jeden Knoten des Suchraums nur einmal. Im Folgenden finden Sie eine kommentierte Version des Codes, in der die Bausteine ausführlicher beschrieben werden.
Die Darstellung einer einzelnen Tafel der Größe w * h ergibt sich aus einer Liste von w Zahlen im Bereich von 0 bis h . Jede Zahl gibt die Stückzahl in der entsprechenden Spalte an. Eine gültige Konfiguration ist also eine Liste, in der die Zahlen von Anfang bis Ende nicht ansteigen (bei jeder Bewegung stellen Sie sicher, dass alle Spalten rechts höchstens so hoch sind wie die ausgewählte).
quelle
Python
23, 141–15 = 126Brute-Force-Minimax-Suche. Für jeden möglichen Zug sehen wir rekursiv, ob der Gegner gewinnen kann, nachdem wir diesen Zug gemacht haben. Ziemlich schwach golfen; jemand anderes sollte es besser machen können. Das fühlt sich wie ein Job für APL an.
win
ist die öffentliche Schnittstelle. Es nimmt die Abmessungen der Karte an, konvertiert sie in eine Kartendarstellung und übergibt sie anw
.w
ist der Minimax-Algorithmus. Es nimmt einen Board-Status an, versucht alle Züge, erstellt eine Liste, deren Elemente Gewinnzügen entsprechen, und gibt True zurück, wenn die Liste leer ist. Standardmäßigf=print
hat das Erstellen der Liste den Nebeneffekt, dass die Gewinnzüge gedruckt werden. Der Funktionsname machte mehr Sinn, wenn er eine Liste mit Gewinnzügen zurückgab, aber dann habe ich ihnnot
vor die Liste verschoben , um Platz zu sparen.for r,p in enumerate(b)for c in xrange(p) if(r+c)
: Alle möglichen Züge durchgehen.1 1
wird als nicht legaler Schritt behandelt, was den Basisfall ein wenig vereinfacht.b[:r]+[min(i,c)for i in b[r:]]
: Konstruiere den Zustand der Tafel nach dem Zug, dargestellt durch Koordinatenr
undc
.w(b[:r]+[min(i,c)for i in b[r:]],max)
: Überprüfen Sie, ob der neue Zustand ein Verlustzustand ist.max
ist die kürzeste Funktion, die ich finden konnte, die zwei ganzzahlige Argumente annehmen und nicht meckern würde.f(r+1,c+1)
: Wennf
gedruckt wird, wird der Zug gedruckt. Was auch immerf
ist, es wird ein Wert zum Auffüllen der Listenlänge erzeugt.not [...]
:not
GibtTrue
für leere Listen undFalse
für nicht leere zurück.Ursprünglicher Python 2-Code, komplett ungolfed, einschließlich Memo-Funktion für viel größere Eingaben:
Demo:
quelle
13x13
Take2x2
und du würdest gewinnen.Perl 6:
113108 Zeichen - 15 = 93 PunkteDieser war hart! Hier ist die nicht zwischengespeicherte Version, die technisch korrekt ist, aber für nicht triviale Eingaben sehr viel Zeit in Anspruch nimmt .
Es funktioniert genau wie die Python-Implementierung von @ user2357112 (ich hätte es nicht ohne seine Arbeit herausfinden können!), Außer dass win () ein Chomp-Board (Array) anstelle einer Breite und Länge benötigt. Es kann verwendet werden wie:
Eine Version mit Memoization, die tatsächlich anständige Eingaben verarbeiten kann (allerdings nicht für Lesbarkeit optimiert):
quelle