Das Spiel
Nim ist ein mathematisches Strategiespiel, bei dem 2 Spieler abwechselnd Gegenstände von verschiedenen Haufen nehmen. Wenn Sie an der Reihe sind, müssen Sie mindestens einen Gegenstand nehmen, und Sie können so viele nehmen, wie Sie möchten, vorausgesetzt, Sie nehmen nur einen Haufen. Der Spieler, der den letzten Gegenstand nimmt, gewinnt! Dies ist ein gelöstes Spiel. Bevor ich auf die Strategie eingehe, können Sie sie hier online spielen .
Die Strategie
Die Gewinnstrategie wird hier unter diesem Link sehr klar und einfach erklärt . Ich werde es mit etwas mehr technischen Begriffen erklären. Der Weg, um dieses Spiel zu gewinnen, besteht darin, immer so viele Gegenstände wie möglich zu nehmen, so dass die binär-digitale Summe immer 0 ist. Betrachten Sie das folgende Brett:
*
* *
* * *
* * * *
* * * * *
1 2 3 4 5
Um die binär-digitale Summe dieser Karte zu finden, müssen Sie:
Konvertieren Sie die Zahl in jeder Zeile in eine Binärzahl. Wir haben also 001, 010, 011, 100 und 101.
Addiere alle Zahlen und ignoriere jegliches Tragen.
001 010 011 100 +101 ---- 001
Sie können auch jede Zahl bitweise x-xieren, wodurch das gleiche Ergebnis erzielt wird.
Wenn die Summe in dieser aktuellen Konfiguration 001 ist, ist dies (noch) kein Gewinnbrett. Aber Sie können es zu einem Gewinnbrett machen! Wenn wir einen Gegenstand aus den Spalten 1, 3 oder 5 entfernen, ist die Summe 0. Dies ist ein Gewinnbrett, was bedeutet, dass der nächste Spieler, der sich bewegt, verliert, sofern Sie keinen Fehler machen. Sie müssen Ihren Zug also immer mit einem Gewinnbrett beenden. Nehmen wir an, Sie nehmen einen Gegenstand aus Spalte 5. Jetzt sieht die Tafel so aus:
* *
* * *
* * * *
* * * * *
1 2 3 4 5
Solange Sie es nicht vermasseln, haben Sie einen garantierten Gewinn. Es gibt nichts, was dein Gegner tun kann, um dich aufzuhalten. Nehmen wir an, er nimmt alle Gegenstände aus Spalte 5.
*
* *
* * *
* * * *
1 2 3 4 5
Wohin würdest du als nächstes gehen? Scrollen Sie noch nicht nach unten und versuchen Sie es selbst herauszufinden.
Im Moment ist die Summe 100. Der beste Zug (und der einzige Gewinnzug) wäre, alles aus Spalte 4 zu nehmen. Das würde das Brett so verlassen:
*
* *
* * *
1 2 3 4 5
und die Summe so
001
010
+011
----
000
das bedeutet, dass Sie in einem Gewinnbrett sind! Yay!
Die Herausforderung
Sie müssen ein Programm oder eine Funktion schreiben, die bei einem Nim-Board einen Gewinnzug oder einen False- Wert zurückgibt , wenn es keinen Gewinnzug gibt.
Deine Eingabe:
Wird das native Listenformat Ihrer Sprache sein, wobei jedes Element in der Liste der Anzahl der Elemente in einer bestimmten Spalte entspricht. Beispielsweise entspricht die Eingabe {4, 2, 1, 0, 3} der folgenden NIM-Karte:
* * * * * * * * * * 1, 2, 3, 4, 5
(optional) Die Anzahl der Zeilen. (Für Sprachen wie C / C ++, bei denen dies aus der Liste selbst nicht bekannt ist.)
Ihre Ausgabe:
Kann zu STDOUT gehen oder von der Funktion zurückgegeben werden
Muss aus zwei Zahlen bestehen: 1) der Spalte, aus der wir entfernen (denken Sie daran, dass die Spalten 0-indiziert sind) und 2) der Anzahl der Elemente, die aus dieser Zeile entfernt werden sollen. Dies kann ein Array mit zwei Elementen, eine Zeichenfolge aus zwei Zahlen usw. sein. Beachten Sie, dass die Antwort möglicherweise länger als zwei Ziffern ist. Die Rückgabe der Zeichenfolge "111" ist daher nicht gültig, da nicht klar ist, ob dies der Fall ist bedeutet "Ein Element aus Spalte 11 entfernen" oder "Elf Elemente aus Spalte 1 entfernen". "1,11" oder "11,1" wären beide akzeptabel.
Wenn keine Antwort erfolgt, geben Sie einen falschen Wert zurück oder drucken Sie ihn aus. Wenn Ihre Sprache nur einen Variablentyp zurückgeben kann (wieder wie C / C ++), wäre eine negative Zahl für die Spalte oder 0 oder weniger für die zu entfernende Zahl akzeptable False-Werte.
Wenn die zu entfernende Spaltennummer oder Nummer zu groß ist, wird dies als ungültige Ausgabe angesehen.
Beispiel Ein- / Ausgänge
[1, 2, 3, 4, 5]
---> [0, 1]
oder [4, 1]
oder[2, 1]
[1, 3, 5, 6]
---> [0, 1]
oder [1, 1]
oder[2, 1]
[1, 2, 0, 0, 5]
---> [4, 2]
[1, 2, 3]
---> ERROR
Wenn Sie eine Funktion anstelle eines vollständigen Programms ausführen möchten, müssen Sie ein vollständiges Programm schreiben, um die Funktion in Aktion zu demonstrieren. Dies wird nicht für Ihre volle Punktzahl angerechnet. Außerdem wird erwartet, dass Programme in angemessener Zeit ausgeführt werden. Ich habe nicht vor, übermäßig große Eingaben einzugeben. Solange Ihr Programm keine Brute-Force-Suche über den gesamten Spielbaum durchführt, sollte es Ihnen gut gehen.
Wie üblich ist dies Code-Golf, daher gelten Standard-Lücken und Antworten werden in Bytes gezählt .
Bestenliste
Hier ist ein Stack-Snippet, mit dem Sie sowohl eine reguläre Rangliste als auch eine Übersicht der Gewinner nach Sprache erstellen können.
Um sicherzustellen, dass Ihre Antwort angezeigt wird, beginnen Sie Ihre Antwort mit einer Überschrift unter Verwendung der folgenden Markdown-Vorlage:
# Language Name, N bytes
Wo N
ist die Größe Ihrer Einreichung? Wenn Sie Ihren Score zu verbessern, Sie können alte Rechnungen in der Überschrift halten, indem man sich durch das Anschlagen. Zum Beispiel:
# Ruby, <s>104</s> <s>101</s> 96 bytes