Herausforderung
Bestimmen Sie bei einem Tic-Tac-Toe-Board in einem beliebigen Format, ob es gültig ist oder nicht. Wenn ein Brett das Ergebnis eines Tic-Tac-Toe-Spiels sein kann, ist es gültig. Zum Beispiel ist diese Karte gültig:
XOX OXO XOXIm Gegenteil, dieses Board ist ungültig:
XXX XXO OOO
Eingang
- Ein vollständiges (9/9) Tic Tac Toe Board (das Ergebnis, nicht das Spiel).
Regeln
- Das Eingabeformat muss alle 512 möglichen Eingabeplatinen abbilden können. Es muss zusammen mit den Anweisungen angegeben werden, um es zu erstellen, wenn es dunkel / unklar ist. Sie müssen die Zeichen der Tafel jedoch einzeln angeben.
- Es müssen zwei mögliche Ausgaben vorhanden sein, eine für die Gültigkeit und eine für die Ungültigkeit.
- Sie können davon ausgehen, dass das Board keine leeren Stellen hat.
Testfälle
Gültig:
XOX OXO XOX XOX XOX OXO XOO OOX OXX OXO XOX OXO
Ungültig:
XXX XXX XXX OOO OOO OOO XXX OOO XXX OOO OOX XXX XXO OXO OOX
Eine kleine Hilfe?
Ein Brett wird (für diese Herausforderung) nur dann als gültig angesehen, wenn die folgenden beiden Bedingungen erfüllt sind:
- Es gibt 5 X und 4 O oder 4 X und 5 O. Zum Beispiel
XXX OXO XXX
wird als ungültig angesehen, da es 7 Xs und 2 Os gibt. - Nur der Spieler mit 5 Punkten hat gewonnen, oder keiner von ihnen hat gewonnen. Zum Beispiel,
XXX OOO OOX
wird als ungültig angesehen, da entweder die Reihe vonO
s oder die Reihe vonX
s zuerst gebildet wird. Die beiden Spieler können nicht gleichzeitig an der Reihe sein.
Der aktuelle Gewinner ist ...
... die Gelee-Antwort von ais523 mit erstaunlichen 26 Bytes!
code-golf
decision-problem
tic-tac-toe
Erik der Outgolfer
quelle
quelle
O O O
X O X
X O X
, um zu zeigen, dass derselbe Spieler sowohl eine horizontale als auch eine vertikale Reihe haben kann.Antworten:
Gelee , 26 Bytes
Probieren Sie es online!
Das Eingabeformat ist etwas ungewöhnlich. Es ist eine Zeichenfolge, die das Board darstellt, jedoch mit Windows-Zeilenumbrüchen (Wagenrücklauf gefolgt von Zeilenumbruch). Zum Beispiel
XXO\r\nOXO\r\nOOX
. (Tatsächlich funktioniert jede aus zwei Zeichen bestehende Auffüllzeichenfolge zwischen den Zeilen, aber Windows-Zeilenumbrüche sind weitaus vertretbarer als die anderen Optionen.)Die Grundidee ist, dass wir nach Zeichen suchen, die viermal in der Eingabe vorkommen, aber in der ursprünglichen Zeichenfolge keine drei gleichmäßig verteilten Vorkommen haben. Bei zwei oder mehr Zeichen Abstand zwischen den Zeilen eines 3 × 3-Gitters sind alle horizontalen, vertikalen und diagonalen Linien gleichmäßig voneinander getrennt, aber keine andere gleichmäßig voneinander getrennte Linie kann drei Elemente enthalten.
Erläuterung:
Das
ð
undµ
s sind Kettentrennzeichen , die das Programm in mehrere Teile aufteilen, die jeweils unabhängig voneinander sind. Ich habe sie durch Leerzeichen unten ersetzt, um die Dinge etwas klarer zu machen.Mit anderen Worten, wir finden die Liste der Zeichen, die genau viermal in der Eingabe vorkommen, und erstellen eine Liste, die jeweils aus drei Kopien besteht. wir finden die Liste aller Teilfolgen, die in der ursprünglichen Zeichenfolge gleichmäßig verteilt sind; und wenn wir die Sekunde von der ersten abziehen, wollen wir, dass das Ergebnis die Länge 1 hat (dh ein Spieler hat vier Mal gespielt, aber nicht gewonnen). Beachten Sie, dass es unmöglich ist, dass beide Spieler vier Mal gespielt haben , da wir auf einem 3 × 3-Raster sind und jedes Feld voll ist . In Jelly ist 1 wahr, 0 ist falsch, daher müssen wir nichts Besonderes tun, um die resultierende Liste in einen Booleschen Wert umzuwandeln. ( Dies
µL
ist jedoch erforderlich, da andernfalls beide“XXX”
und“OOO”
möglicherweise wahrheitsgemäße Ausgabewerte vorliegen und die Frage erfordert, dass alle gültigen Karten dieselbe Ausgabe liefern.)quelle
JavaScript (ES6),
8887 BytesÜbernimmt die Eingabe als Zeichenfolge aus 9
0
und1
Zeichen und gibt1
für gültig,0
für ungültig zurück. Wir sortieren die Zeichen in der Reihenfolge. Wenn die mittleren drei Zeichen jetzt gleich sind, ist die Tafel ungültig, da zu viele Teile vorhanden sind. Andernfalls konvertieren wir die ursprüngliche Karte in eine Binärdatei und spiegeln die Bits, wenn mehr0
s als1
s vorhanden sind. Zu diesem Zeitpunkt ist die0
Karte gültig, wenn sie keine drei Zeilen enthält. Wir testen daher einfach alle acht Zeilen über ein Array von Bitmasken. Bearbeiten: 1 Byte dank @ETHproductions gespeichert.quelle
Python 3,
13112712510096 BytesFür einen anderen algorithmischen Ansatz (und einen, der wirklich für diese Multi-Byte-Golfsprachen mit integrierter Komprimierung geeignet ist), anstatt zu berechnen, ob die Karte gültig ist, geben wir eine 512-Bit-Zahl an, bei der jedes Bit angibt, ob oder nicht Eine bestimmte Karte ist gültig oder nicht und übergibt einen Binärwert, der die Karte darstellt. Außerdem kann aufgrund der Symmetrie die zweite Tabellenhälfte zusammen mit einer Reihe von Nullen eliminiert werden:
Der Testwert:
Wird als Binärwert dargestellt
0b111010111
und die Funktion gibt einen Wert ungleich Null zurück, wenn die Karte gültig ist.quelle
a&(1<<b)
keine Klammern erforderlich sind.if b>255:b=511-b
!if
.Batch, 140 Bytes
Nimmt Eingaben als neun separate Befehlszeilenargumente und -ausgaben
1
für gültig und0
ungültig an. Verfolgt, wie oft eineO
und eine orthogonale Linie vonOOO
oder angezeigt wirdXXX
. Praktischerweise können wir mit Batch eine Ganzzahlarithmetik indirekt ausführen, sodass wir nicht inkrementieren,%%l
sondern stattdessen eine Variable (obwohl wir nur an den drei genannten Variablen interessiert sind). Wir müssen dann testen, ob entwederX
nicht gewonnen hat und es fünfO
Sekunden gibt oder obO
nicht gewonnen hat und es vierO
Sekunden gibt.quelle
Mathematica,
82-75BytesVielen Dank an Martin Ender für die Einsparung von 7 Bytes!
Unbenannte Funktion, die eine 3x3 verschachtelte Liste von Einsen und Nullen als Eingabe und Ausgabe verwendet
True
oderFalse
.Verwendet eine handliche Flexibilität der
Total
Funktion (hier golfent
): Bei einem gegebenen Beispiel-Array summiert dere = { {1,2,3} , {4,5,6} , {7,8,9} }
Befehlt[e]
die drei Vektoren (hier ergibt sich{12,15,18}
); der Befehlt/@e
summiert jede Unterliste einzeln (hier ergibt sich{6,15,24}
); und der Befehle~t~2
summiert alle neun Elemente (hier ergeben45
).Also testen wir zuerst mit
3<(b=#~t~2)<6
, ob die Gesamtzahl von 1s 4 oder 5 ist; wenn nicht, verlassen wir mitFalse
. In diesemc=If[b>4,1-#,#]
Fall erzwingen wir vier Einsen, nicht fünf. Dann berechnen wir die Spaltensumment[c]
, die Zeilensumment/@c
, die Summe der HauptdiagonaleTr@c
und die Summe der entgegengesetzten DiagonaleTr@Reverse~c
und verwenden~FreeQ~3
, um zu überprüfen, ob3
dies auf keiner Ebene in diesen berechneten Summen auftritt.Amüsante Randnotiz: Im Gegensatz zu den meisten Erscheinungen auf dieser Website wird hier
Tr
keine eindimensionale Liste zusammengefasst, sondern tatsächlich wie geplant verwendet - um die Spur einer zweidimensionalen Matrix zu berechnen!quelle
Pyth - 36 Bytes
Ich schließe Diagas ein und benutze stattdessen zwei Ternaries.
Test Suite
quelle
JavaScript (ES6), 101 Byte
Übernimmt die Eingabe als 9-Bit-Binärmaske, wobei
X = 1
undO = 0
(MSB = obere linke Zelle, LSB = untere rechte Zelle).Testfälle
Code-Snippet anzeigen
quelle
Python 2,
1581321099291123 BytesDie Eingabe ist eine Liste / ein Tupel von Zeilen, von denen jede aus drei Tupeln von Zeichenfolgen besteht, z.
[('X', 'O', 'X'), ('O', 'X', 'O'), ('X', 'O', 'X')]
Durch Ignorieren der Diagonalen pro @ Maltysen-Antwort wurden einige Bytes gespart, was auch den folgenden Ausdruck verkürzte.Danke @vaultah fürs Speichern1718 Bytes.Es erweist sich als notwendig, die Diagonalen zu überprüfen, was einen Großteil der obigen Einsparungen beseitigt hat.
Probieren Sie es hier aus.
Erläuterung
f
ist die abgeflachte Eingabe für das Schneiden.w
enthält die Zeichen mit Gewinnsequenzen.Zählen Sie die Vorkommen der einzelnen Gewinncharaktere, die entweder 0 sind, wenn sie
w
leer sind, oder 5, wenn sielen(w)
1 sind. Die 10-Summe, wenn beide eine Gewinnsequenz haben, ist unmöglich. Der Gewinner mit 5 impliziert, dass der Verlierer 4 hat. Sie können nicht> 5 ohne eine Gewinnsequenz haben.quelle
lambda b:len({x[0]for x in b+zip(*b)if len(set(x))==1})<2and set(map(
b.count,'XO'))=={4,5}
speichert einige Bytes....and{4,5}==set(map(
b.count,'XO'))
ein weiteres Byte speichert.R
8882 BytesAlle Kombinationen von drei ganzen Zahlen von 1 bis 9, die sich zu 15 summieren, sind die Zeilen / Spalten / Diagonalen des unten gezeigten Quadrats.
Die Funktion nimmt Eingaben als Vektor von Booleschen Werten an, T für "X", F für "O", was die abgeflachte Darstellung der Karte ist. ABER diese werden neu angeordnet, so dass ihr Index mit der Zahl im Quadrat in der Reihenfolge (2,7,6,9,5,1,4,3,8) übereinstimmt. Diese Reihenfolge kann erreicht werden, indem die Platte auf normale Weise abgeflacht und dann mit c (6,1,8,7,5,3,2,9,4) geschnitten wird. Also das
wird dargestellt als:
welches ist:
Die Funktion ermittelt zunächst, ob es einen Spieler mit genau vier Markierungen gibt. In diesem Fall verwendet die Funktion die Tatsache, dass sich die Summe zu 15 addiert, um zu bestimmen, ob dieser Spieler einen Drei-in-einer-Reihe hat (das Brett ist ungültig, wenn dieser Spieler dies tut).
Wenn Sie eine konventionell abgeflachte Karte als Eingabe verwenden möchten, sieht der Code stattdessen folgendermaßen aus:
Ich bin neu in diesem Bereich, würde gerne beraten.
quelle
if()
stattdessen Folgendes verwenden :f=function(x)
if(sum(x)%in%4:5,all(apply(combn(which(x==(sum(x)<5)),3),2,sum)!=15),F)
. Wohlgemerkt nicht ausgiebig getestet. Backticks ruinieren Code, aber es istbacktick if backtick(
.x=scan();
if(sum(x)%in%4:5,all(apply(combn(which(x==(sum(x)<5)),3),2,sum)!=15),F)
und Eingabe als1
und0
. 82 Bytes.JavaScript (ES6),
145139131127 ByteEingabe als durch Leerzeichen getrennte Zeichenfolge, z
"XOX OXO XOX"
. Ausgänge1
für eine ungültige Karte,0
für eine gültige. Dies ist offensichtlich nicht die beste Technik, zumindest nicht mit JavaScript ...Dies überprüft grundsätzlich, ob beide der folgenden Aussagen zutreffen:
O
s UNDDer reguläre Ausdruck ist zu prüfen, ob ein Spiel entschieden wurde. Es passt zu einer Tafel, wenn es Läufe der Länge 3 eines Zeichens gibt, wobei 0 (Zeile), 2 (Diagonale rechts unten), 3 (Spalte) oder 4 (Diagonale links unten) jedes Paar trennen.
Testschnipsel
Code-Snippet anzeigen
quelle
Ruby,
104 9991 BytesEingabeformat: Binäre Zeichenfolge mit 9 Symbolen (0s und 1s), die die Karte darstellt, z. B. der erste Testfall
101010101
. Wandle es zuerst in eine Binärzahl um, überprüfe ob popcount 4 oder 5 ist, wenn es 5 ist, invertiere die Zahl, so dass wir immer 4 haben. Überprüfe, ob drei von ihnen ausgerichtet sind (Maskierung mit horizontal, vertikal, diagonal).TL; DR : Gibt false zurück, wenn der Spieler mit 4 Punkten gewonnen hat, andernfalls true.
Danke Jordan für die Kommentare,
Ich kann den UTF-8-String nicht reproduzieren, der ein weiteres Byte speichern würde.
quelle
.select{...}[0]
mit.find{...}
."8ǀĤITđ".unpack("U*")
(falls bei der Übersetzung etwas verloren geht, ist die Zeichenfolge das Ergebnis des Aufrufspack("U*")
des ursprünglichen Arrays; es sind 12 Byte).any?
stattdessennone?
die Ausgabe spiegeln und ein ganzes Byte speichern?Perl 6 ,
10399 BytesEin Lambda, das eine Liste von Listen wie annimmt
(('X','O','X'), ('O','X','O'), ('X','O','X'))
und einen Bool zurückgibt.Das funktioniert so:
c
. (Wenn keine Markierung genau fünfmal erscheint, enthält dies einen falschen Wert.)c
die Wahrheit stimmt und jede Gewinnlinie vom Typ istc
.quelle
PHP, 125 Bytes
Ich hatte die gleiche Idee wie Arnauld : Die Karte ist gültig, wenn entweder 4 oder 5 Bits gesetzt sind und entweder
X
oderO
oder niemand eine Streifen hat (aber nicht beide).Um eine Eingabe aus dem Feld zu generieren, ersetzen Sie
X
mit1
undO
mit0
, verbinden Sie die Zeilen und konvertieren Sie die Binärzahl in eine Dezimalzahl. Geben Sie als Befehlszeilenargument an.druckt
1
für gültig; leere Ausgabe für ungültig. Laufen Sie mit-r
.Nervenzusammenbruch
quelle
Schnell, 178 Bytes
quelle
ES6 (Javacript),
130,138117 BytesEDITS:
Ein extrem geradliniger Ansatz. Kann wohl etwas weiter golfen werden.
Akzeptiert Eingaben als 9 separate Argumente, 1es und 0es
Argumente: 1-3 - erste Reihe, 4-6 - zweite Reihe, 7-9 - dritte Reihe.
Golf gespielt
Interaktiver "Prüfstand"
quelle
[1,0,1,1,0,1,0,1,0]
(XOX XOX OXO
).a+b+c+d+e+f+g+H+i
anstattF.reduce((r,c)=>r+=c*1)
(an welchem Punkt brauchst du es nichtF
) b) schreiben.includes(C)
(und weiter mit demC
Wert von inline )?OOO XXX OXO
ein Fehler?