Determina la vittoria in Tictactoe


19

Giochiamo a golf nel codice!

Dato uno stato della scheda tic-tac-toe (Esempio :)

|x|x|o|
|x|o|x|
|o|o|x|

Determina se un gioco è wina loseo cat. Il tuo codice dovrebbe generare una di queste opzioni dato uno stato. Il gioco sopra dovrebbe essere prodottolose

Giusto per essere chiari: una vittoria è definita come ogni 3 xs di fila (diagonale, orizzontale, verticale). una perdita è di 3 os di fila, mentre una catpartita in nessuna di fila.

Per rendere le cose interessanti, devi determinare la struttura di input per lo stato, che devi quindi spiegare. Ad esempio xxoxoxooxè uno stato valido come visto sopra in cui ciascuno dei caratteri viene letto da sinistra a destra, dall'alto verso il basso. [['x','x','o'],['x','o','x'],['o','o','x']]è il gioco in array multidimensionale letto in modo simile. Mentre 0x1a9che è esadecimale per 110101001lavoro potrebbe come una compressione adatto dove 1può essere manipolata per xs e 0può essere manipolato per o.

Ma quelle sono solo alcune idee, sono sicuro che potresti averne molte tue.

Regole di base:

  1. Il programma deve essere in grado di accettare qualsiasi stato valido.
  2. La forma di input deve essere in grado di rappresentare qualsiasi stato.
  3. "Lo stato di vittoria deve essere determinato dal tabellone"
  4. Assumi una tavola completa
  5. Winprima losead esempio nel caso "xxxoooxxx"

Vince il conteggio dei personaggi più basso


1
Mi piace questa struttura di input:, (win|lose|cat) [xo]{9}dove la prima parola indica se il gioco è una vittoria, una perdita o un gatto (?) Per il giocatore x. In grado di rappresentare qualsiasi stato.
Runer112,

2
Posso suggerire una regola come "Lo stato di vincita deve essere determinato dal tabellone" o "L'input non deve contenere informazioni tranne lo stato di tabellone"?
undergroundmonorail

3
Supponiamo che vengano giocate solo partite legali? In tal caso, alcuni stati sarebbero impossibili, ad esempio XXX OOO XXX, ma per il resto alcuni stati di pensione completa includono questo come quarto risultato impossibile, in cui X vince ma anche O vince.
Riot

10
perché "gatto" per interesse?
Chris,

7
@DylanMadisetti: non l'ho mai sentito prima e googlign per "vinci perdi gatto" non ha inventato nulla. Sarei andato con la cravatta o disegnare personalmente. O nel caso di questo gioco forse "inevitabilità". ;-) Non mi dispiace molto per quanto riguarda la concorrenza. Una stringa è una stringa. ;-)
Chris,

Risposte:


11

Ruby 2.0, 85 caratteri

Ecco una semplice soluzione basata su maschera di bit in Ruby:

d=gets.hex
$><<[292,146,73,448,56,7,273,84].map{|m|d&m<1?:lose:d&m<m ?:cat: :win}.max

Il tabellone è rappresentato come un numero esadecimale, composto da nove bit corrispondenti ai nove quadrati. 1 è un X, 0 è un O. Questo è proprio come 0x1a9nell'esempio nella domanda, sebbene 0xsia facoltativo!

Probabilmente c'è un modo migliore per fare le maschere di bit, quindi semplicemente codificare una grande lista. Prenderò felicemente suggerimenti.

Guardalo in esecuzione su Ideone qui .


1
La tua lista contiene 273due volte. E mi piace davvero l' maxidea!
Ventero,

1
Oh @Ventero, sempre con le oscure ottimizzazioni (grazie)
Paul Prestidge,

Possono esserci spazi vuoti su una tavola. Il formato di input non tiene conto di ciò e pertanto non può rappresentare uno stato di gioco valido.
Stephen Ostermiller,

2
Regola 4 di @StephenOstermiller: assumere una scheda completa. Hai ragione nel dire che questa regola è forse contraddetta dalle regole 1 e 2, tuttavia se leggi tutti i commenti sulla domanda penso che questo sia nello spirito della domanda (le schede incomplete non sono coperte, mentre le schede complete ma illegali lo sono). Tuttavia, penso che ottale sarebbe un formato di input più intuitivo rispetto a hex.
Level River St

1
Capito, pensavo che completo significasse qualcosa di diverso.
Stephen Ostermiller,

10

Mathematica, 84 caratteri

a=Input[];Which[Max@#>2,win,Min@#<1,lose,1>0,cat]&@{Tr@a,Tr@Reverse@a,Tr/@a,Total@a}

Formato di input: {{1, 1, 0}, {1, 0, 1}, {0, 0, 1}}


Cosa sta succedendo qui?
Seequ,

3
@TheRare Inizia da destra. Tr@aè la traccia del campo (somma sopra la diagonale), Tr@Reverse@aè la traccia del campo capovolto (alcuni sopra la diagonale), Tr/@aviene Trapplicata a ciascuna riga, che ti dà la somma su ogni riga, Total@ati dà la somma su ogni colonna. Quindi, in pratica, hai tutte e 8 le linee che devi controllare. Quindi la Whichcosa viene applicata a quello (sostanzialmente if/elseif/elseun'istruzione), dove #rappresenta quell'elenco di 8 valori. ifc'è un 3che vinci, else ifc'è un 0che perdi, else if 1>0(vero) cat.
Martin Ender,

6

Bash: 283 262 258

Dotato di un'interfaccia relativamente amichevole.

t(){ sed 's/X/true/g;s/O/false/g'<<<$@;}
y(){ t $(sed 's/X/Q/g;s/O/X/g;s/Q/O/g'<<<$@);}
f(){($1&&$2&&$3)||($1&&$5&&$9)||($1&&$4&&$7)||($2&&$5&&$8)||($3&&$5&&$7)||($3&&$6&&$9)||($4&&$5&&$6)||($7&&$8&&$9)}
f $(t $@)&&echo win||(f $(y $@)&&echo lose)||echo cat

Eseguire bash tictactoe.sh O X O X O X X O X

Nota: l'elenco di 9 posizioni è una rappresentazione matrice standard. Non importa se il tabellone è rappresentato come maggiore di colonna o maggiore di riga, letto da sinistra a destra o dall'alto verso il basso - i giochi di punte e croci (o tic tac toe se insisti) sono simmetrici, quindi l'ordine di input dovrebbe essere irrilevante al risultato in ogni corretta implementazione, purché l'input sia lineare.

Modifica: grazie a hjk per suggerimenti sulla sintassi delle funzioni più brevi.


Considerare t() { ... }invece di function t? Può salvare alcuni personaggi lì. :)
hjk

Mi ero completamente dimenticato della sintassi della funzione alternativa - grazie!
Riot

Gli spazi non sono richiesti <<<per salvare altri quattro caratteri.
Michael Mior,

4

Befunge 93 - 375

Accetta una stringa binaria come input.

99>~\1-:!!|>v  
>0v>v>v   >^$>v
^+ + +    0<:p:
>#+#+#+    ^246
^+ + +    0<265
>#+#+#+    ^pp6
^+ + +    0<2++
 #+#+#+     55p
   0 0      552
  >^>^>0v   +46
v+ + +  <   ppp
>0 + + + v  444
   v!!-3:<< 246
  v_"ni"v   ppp
  0v" w"<   :+:
  \>,,,,@   266
  ->,,,@    555
  !^"cat"_^ 645
  !>:9-! ^  +:+
  >|        p:p
   >"eso"v  6p6
 @,,,,"l"<  246
            p2p
            >^ 
  v       <^  <

Legge la stringa. Bruteforce lo scrive (la striscia più verticale a destra) come una matrice tra il

^+ + + 
>#+#+#+
^+ + + 
>#+#+#+
^+ + + 
 #+#+#+

aggiungendo reticolo (idk). Determina la somma di colonne, righe e due diagnosi. Confronta questi valori con 3 ("vinci") o 0 ("perdi"), altrimenti se tutti i valori sono uguali a 1 o 2, allora disegna ("gatto").


4

GolfScript, 27 caratteri

70&.{~"win""lose"if}"cat"if

Il formato di input è una stringa composta da otto cifre ottali, ognuna (ridondante) che codifica per tre quadrati consecutivi di bordo:

  • Le prime tre cifre codificano ciascuna una singola riga della scheda, dall'alto verso il basso e da sinistra a destra.
  • Le tre cifre seguenti codificano ciascuna una singola colonna della scheda, da sinistra a destra e dall'alto in basso.
  • Le ultime due cifre codificano ognuna una delle diagonali (prima da in alto a sinistra in basso a destra, poi da in basso a sinistra in alto a destra).

Per codificare una sequenza (riga / colonna / diagonale) di tre quadrati come una cifra ottale, sostituisci ogni xnella sequenza con 1 e ogni ocon uno 0 e interpreta la sequenza risultante di uno e zeri come un numero binario compreso tra 0 e 7 compreso.

Questo formato di ingresso è abbastanza ridondante (tutti posizioni di bordo sono codificati almeno due volte, con la posizione centrale codificato quattro volte), ma non senza ambiguità rappresenta eventuale stato di un bordo tic-tac-toe completamente riempito, e non direttamente codificare la vincitore nell'input.

L'input può, facoltativamente, contenere spazi o altri delimitatori tra le cifre. In realtà, tutto il programma davvero preoccupa è o meno la stringa di input contiene le cifre 7o 0.

Ad esempio, la scheda di esempio:

|x|x|o|
|x|o|x|
|o|o|x|

può essere rappresentato dall'input:

651 643 50

Per comodità, ecco un programma GolfScript per convertire un layout di una scheda grafica ASCII, come mostrato nella sfida precedente, in una stringa di input adatta a questo programma:

."XOxo"--[{1&!}/]:a[3/.zip"048642"{15&a=}%3/]{{2base""+}%}%" "*

Questo convertitore ignora qualsiasi carattere diverso da xe o, in entrambi i casi, nel suo input. Produce una stringa a una cifra (completa di delimitatori di spazio come mostrato sopra) adatta per alimentare il programma di determinazione delle vincite sopra, quindi la concatenazione di questi due programmi può essere usata per determinare il vincitore direttamente dalla tavola da disegno ASCII.

Inoltre, ecco un convertitore inverso, solo per dimostrare che l'ingresso effettivamente rappresenta in modo inequivocabile la scheda:

.56,48>-- 3<{2base-3>{"ox"=}%n}%"|".@@*+);

Ps. Ecco una demo online di questa soluzione.


2
Il formato di input sembra un po 'un cheat in quanto gran parte del lavoro avviene nella produzione dell'input.
Arkku,

@Arkku: Beh, sì, lo è, ma la domanda dice esplicitamente che "devi determinare la tua struttura di input per lo stato - che poi devi spiegare". Mostra anche una stringa esadecimale a bit come esempio di un formato di input valido; l'unica differenza tra questo e il mio formato di input è che riordinare e duplicare alcuni bit.
Ilmari Karonen,

6
È esattamente la duplicazione che sembra un imbroglione. (ad esempio, esso non codificare direttamente il vincitore come la presenza di 7 o 0 in ingresso)
Arkku

Tuttavia, questa è una codifica intelligente, è ridondante, ma rende la ricerca della soluzione molto più efficiente di qualsiasi codifica non ridondante!
ARRG,

3

Python 2 - 214 byte

b=eval(raw_input())
s=map(sum,b)
w,l='win','lose'
e="if min(s)<1:print l;a\nif max(s)>2:print w;a"
exec e+'\ns=map(sum,zip(*b))\n'+e
m=b[1][1]
for i in 0,2:
 if m==b[0][i]==b[2][abs(i-2)]:print[l,w][m];a
print'cat'

Sono sicuro che ci sono miglioramenti da apportare.

Correre:

python2 tictactoe.py <<< '[[1,1,1],[1,0,1],[0,1,0]]'

che rappresenta questo consiglio:

X|X|X
-----
X|O|X
-----
0|X|0

Esce con NameErrorun'eccezione in ogni caso tranne cat.


Whoa, non l'ho mai saputo <<<! +1 solo per quello.
Greg Hewgill,

@GregHewgill È abbastanza conveniente. ./whatever <<< 'blah blah blah'è lo stesso echo -n 'blah blah blah' | ./whateverma senza avere un processo completamente separato per echo.
undergroundmonorail

@undergroundmonorail echoin bashè in realtà un built-in, quindi non biforca un nuovo processo
Bob

@GregHewgill si chiama herestring

3

Haskell, 146 caratteri

Per rendere le cose interessanti, devi determinare la struttura di input per lo stato, che devi quindi spiegare.

OK :). La mia rappresentazione di una tavola è uno di quei 126 caratteri

ĻŃŇʼnŊœŗřŚşšŢťŦŨųŷŹźsƁƂƅƆƈƏƑƒƕƖƘƝƞƠƤƳƷƹƺƿǁǂDždžLjǏǑǒǕǖǘǝǞǠǤǯDZDzǵǶǸǽǾȀȄȍȎȐȔȜȳȷȹȺȿɁɂɅɆɈɏɑɒɕɖɘɝɞɠɤɯɱɲɵɶɸɽɾʀʄʍʎʐʔʜʯʱʲʵʶʸ''ˀˎː˔~˭ˮ˰˴˼̌

Ecco la soluzione in 146 caratteri:

main=interact$(\x->case(head x)of h|elem h "ĻŃœťŦŨųŷŹƁƂƅƈƕƠƤƳƿǂdžǞǤǵǾȀȳȿɁɅɑɒɘɝɠɤɵɽʀʐʽʾː˭ˮ˰˴˼̌"->"lose";h|elem h "ƏƝƞƹǁLjǑǝȍȺɆɈɶɾʎʸ"->"cat";h->"win")

Ed ecco come funziona, come uno script haskell:

import Data.List (subsequences, (\\))
import Data.Char (chr)

-- A set of indexes [0-8] describing where on the board pieces of a single color have been played
-- For example the board "OxO;Oxx;xxO" is indexes [0,2,3,8]
type Play = [Int]

-- There are 126 filled tic tac toe boards when X plays first.
--      (This is a combination of 4 OHs among 9 places : binomial(9 4) = 126)
-- perms returns a list of all such possible boards (represented by the index of their OHs).
perms = filter (\x -> 4 == length x) $ subsequences [0..8]

-- We now create an encoding for plays that brings them down to a single char.
-- The index list can be seen as an 9 bit binary word [0,2,3,8] -> '100001101'
-- This, in turn is the integer 269. The possible boards give integers between 15 and 480.
-- Let's call those PlayInts
type PlayInt = Int

permToInt [] = 0
permToInt (x:xs) = (2 ^ x) + permToInt xs 

-- Since the characters in the range 15-480 are not all printable. We offset the chars by 300, this gives the range 
-- ĻŃŇʼnŊœŗřŚşšŢťŦŨųŷŹźſƁƂƅƆƈƏƑƒƕƖƘƝƞƠƤƳƷƹƺƿǁǂDždžLjǏǑǒǕǖǘǝǞǠǤǯDZDzǵǶǸǽǾȀȄȍȎȐȔȜȳȷȹȺȿɁɂɅɆɈɏɑɒɕɖɘɝɞɠɤɯɱɲɵɶɸɽɾʀʄʍʎʐʔʜʯʱʲʵʶʸʽʾˀ˄ˍˎː˔˜˭ˮ˰˴˼̌
-- Of all distinct, printable characters
uOffset = 300

-- Transform a PlayInt to its Char representation
pIntToUnicode i = chr $ i + uOffset

-- Helper function to convert a board in a more user friendly representation to its Char
-- This accepts a representation in the form "xooxxxoxo"
convertBoard s = let play = map snd $ filter (\(c, i) -> c == 'o') $ (zip s [0..]) :: Play 
    in pIntToUnicode $ permToInt play

--
-- Now let's cook some data for our final result
--  

-- All boards as chars
allUnicode = let allInts = map permToInt perms 
    in map pIntToUnicode allInts

-- Now let's determine which boards give which outcome.

-- These are all lines, columns, and diags that give a win when filled
wins = [
        [0,1,2],[3,4,5],[6,7,8], -- lines
        [0,3,6],[1,4,7],[2,5,8], -- columns
        [0,4,8],[2,4,6] -- diagonals
    ]

isWin :: Play -> Bool   
isWin ps = let triplets = filter (\x -> 3 == length x) $ subsequences ps -- extract all triplets in the 4 or 5 moves played
    in any (\t -> t `elem` wins) triplets -- And check if any is a win line

-- These are OH wins
oWins = filter isWin perms
-- EX wins when the complement board wins
xWins = filter (isWin . complement) perms
    where complement ps = [0..9] \\ ps
-- And it's stalemate otherwise
cWins = (perms \\ oWins) \\ xWins

-- Write the cooked data to files
cookData = let toString = map (pIntToUnicode . permToInt) in do
  writeFile "all.txt" allUnicode
  writeFile "cWins.txt" $ toString cWins
  writeFile "oWins.txt" $ toString oWins
  writeFile "xWins.txt" $ toString xWins

-- Now we know that there are 48 OH-wins, 16 stalemates, and 62 EX wins (they have more because they play 5 times instead of 4).
-- Finding the solution is just checking to which set an input board belongs to (ungolfed :)
main = interact $ \x -> case (head x) of -- Only consider the first input char
    h | elem h "ĻŃœťŦŨųŷŹƁƂƅƈƕƠƤƳƿǂdžǞǤǵǾȀȳȿɁɅɑɒɘɝɠɤɵɽʀʐʽʾː˭ˮ˰˴˼̌" -> "lose" -- This string is == oWins
    h | elem h "ƏƝƞƹǁLjǑǝȍȺɆɈɶɾʎʸ" -> "cat" -- And this one == cWins
    h -> "win"

3

JavaScript, 420 caratteri

if((s&0x3F000)==0x3F000||(s&0x00FC0)==0x00FC0||(s&0x0003F)==0x0003F||(s&0x030C3)==0x030C3||(s&0x0C30C)==0x0C30C||(s&0x30C30)==0x30C30||(s&0x03330)==0x03330||(s&0x30303)==0x30303)return 'win'
if((s&0x3F000)==0x2A000||(s&0x00FC0)==0x00A80||(s&0x0003F)==0x0002A||(s&0x030C3)==0x02082||(s&0x0C30C)==0x08208||(s&0x30C30)==0x20820||(s&0x03330)==0x02220||(s&0x30303)==0x20202)return 'lose'
if((s&0x2AAAA)==0x2AAAA)return 'cat'

In questa versione, scontiene un numero intero che rappresenta lo stato del tabellone. È un array di bit di valore in cui due bit rappresentano ogni quadrato sulla scheda:

  • 10 - X
  • 11 - O
  • 00 - Quadrato vuoto

Questa soluzione utilizza la manipolazione dei bit per testare ciascuna delle otto possibili configurazioni "tre di fila" (le verifica ciascuna due volte, una per X e una per O).

Vi presento questo con una piccola minificazione dal mio sito web Tic-Tac-Toe dove questodetectWin funzione è utilizzata come parte di un vero gioco Tic-Tac-Toe.


6
Bene, questo potrebbe essere chiamato bruto forzandolo.
Seequ,

2

Rubino, 84 caratteri

$><<(gets.tr("01","10")[r=/0..(0|.0.)..0|000(...)*$|^..0.0.0/]?:win:~r ?:lose: :cat)

Soluzione semplice, basata su RegExp. Il formato di input è una stringa binaria di 9 cifre, ad esempio 110101001per la scheda di esempio fornita nella domanda.

Rubino, 78 caratteri

$><<(gets.tr("ox","xo")[r=/o...(o|.o.)...o|ooo|o_.o._o/]?:win:~r ?:lose: :cat)

Formato di input: xxo_xox_oox


1

Haskell, 169

main=interact$(\x->last$"cat":[b|(a,b)<-[("ooo","lose"),("xxx","win")],any(==a)x]).(\x->x++(foldr(zipWith(:))(repeat[])x)++map(zipWith(!!)x)[[0..],[2,1,0]]).take 3.lines

Formato di input: "X" è rappresentato solo da x, "O" solo dao . All'interno di ogni riga, i caratteri sono simultanei senza spazi, ecc. Le righe sono separate da nuove linee.

Genera tutte le possibili righe / colonne / diagonali, quindi filtra in [("ooo","lose"),("xxx","win")]base alla loro esistenza sul tabellone, quindi seleziona la seconda parola nella tupla, quindi sappiamo quali giocatori hanno vinto. Anticipiamo in "cat"modo da poter prendere l'ultimo elemento della lista come nostro vincitore. Se entrambi i giocatori hanno vinto, "win"saranno gli ultimi (la comprensione della lista mantiene l'ordine). Poiché "cat"è sempre il primo, se esiste un vincitore, verrà scelto, ma per il resto esiste ancora un ultimo elemento in quanto il prepending "cat"garantisce la non vacuità.

EDIT: rasato 3 caratteri modificando la comprensione dell'ultima lista in map.


1

C, circa 150

È mezzanotte qui e non ho fatto alcun test , ma pubblicherò comunque il concetto. Ci tornerò domani.

L'utente inserisce due numeri ottali (volevo usare binario ma per quanto ne so C supporta solo ottali):

a rappresenta il quadrato centrale, 1 per una X, 0 per una O

b è un numero di nove cifre che rappresenta i quadrati perimetrali, girando attorno al tabellone iniziando in un angolo e finendo nello stesso angolo (con la ripetizione di quell'angolo solo), 1 per una X, 0 per una O.

Esistono due modi per vincere:

  1. il quadrato centrale è X ( a= 1) e due quadrati opposti sono anche X ( b&b*4096è diverso da zero)

  2. tre quadrati perimetrali adiacenti sono X ( b/8 & b & b*8è diverso da zero). Questa è una vincita valida solo se il quadrato centrale è un quadrato di bordo, non un quadrato d'angolo, quindi è necessario applicare anche la maschera m, per evitare i casi quadrati d'angolo.

La perdita viene rilevata usando la variabile c, che è l'inverso di b.

int a,b,c,m=010101010;
main(){
    scanf("%o%o",a,b);c=b^0111111111;
    printf("%s",(a&&b&b*4096)|(b/8&b&b*8&m)?"win":((!a&&c&c*4096)|(c/8&c&c*8)?"lose":"cat"));
}

Hai dimenticato di applicare la maschera mnel rilevamento "perde" - c/8&c&c*8. Ho ricodificato il tuo codice (senza testarne il funzionamento) come segue: int a,b;t(v){return a&&v&v<<12||v/8&v&v*8&0x208208;}main(){scanf("%o%o",a,b);printf("%s",t(b)?"win":t(b^0x1249249)?"lose":"cat");}(130 caratteri). Il test ripetuto è stato abbastanza lungo per essere estratto in una funzione di test t(); questo elimina la necessità di ce m; le costanti convertite in esadecimale per salvare un carattere ciascuno.
Toby Speight,

Ho appena notato che printfnon è necessaria una stringa di formato - basta fornire la stringa di risultato come formato - oppure puts, poiché la domanda non richiede una nuova riga dopo l'output! (salva altri 7 caratteri).
Toby Speight,

1

bash, 107 103

Genera ed esegue uno script sed.

Formato I / O: oxo-oox-xoooutput lose(utilizzare a -per separare le righe). Input su stdin. Richiede GNU sed per il ccomando.

Ho interpretato la regola 5 come "se sono possibili sia la vittoria che la sconfitta, scegli la vittoria".

Codice principale

Questa è la risposta effettiva.

Niente di veramente interessante. Definisce $bcome /cwinsalvare i caratteri, quindi definisce la parte vincente dello script, quindi usa sed y/x/o/\;s$b/close/per convertire xin oe cwinin close(generando così le condizioni perdenti). Invia quindi le due cose e ccat(che verrà emesso catse nessuna condizione di vittoria / perdita è abbinata) a sed.

b=/cwin
v="/xxx$b
/x...x...x$b
/x..-.x.-..x$b
/x-.x.-x$b"
sed "$v
`sed y/x/o/\;s$b/close/<<<"$v"`
ccat"

Codice generato

Questo è lo script sed generato ed eseguito dallo script Bash.

Nelle regex, .corrisponde a qualsiasi personaggio e dopo di loro cTEXTstampa TEXT ed esce se la regex è abbinata.

Questo può essere eseguito come uno script sed autonomo. È lungo 125 caratteri, puoi contarlo come un'altra soluzione.

/xxx/cwin
/x...x...x/cwin
/x..-.x.-..x/cwin
/x-.x.-x/cwin
/ooo/close
/o...o...o/close
/o..-.o.-..o/close
/o-.o.-o/close
ccat

1

Python 3, 45

L'ingresso è in i, che è un elenco di numeri che rappresentano ciascuna riga, colonna e diagonale del tabellone, ad esempio:

X X O
O X O
O O X

è rappresentato da [6, 2, 1, 4, 6, 1, 7, 4].

Codice :('cat','lose','win')[2 if 7 in i else 0 in i]


1

Dardo - 119

(Vedi dartlang.org ).

Versione originale con RegExp: 151 caratteri.

main(b,{w:"cat",i,p,z}){
 for(p in["olose","xwin"])
   for(i in[0,2,3,4])
     if(b[0].contains(new RegExp('${z=p[0]}(${'.'*i}$z){2}')))
       w=p.substring(1);
  print(w);
}

L'immissione sulla riga di comando è di 11 caratteri, ad es. "Xxx | ooo | xxx". Qualsiasi carattere non xo può essere utilizzato come delimitatore.

Gli spazi bianchi e le nuove righe principali dovrebbero essere omessi prima di contare i caratteri, ma ho tagliato lo spazio bianco interno ove possibile. Vorrei che ci fosse un modo più piccolo per realizzare la sottostringa.

Versione bit-base recusiva: 119 caratteri. L'ingresso deve essere un numero di 9 bit con 1s che rappresenta 'x' e 0s che rappresenta 'o'.

main(n){
  n=int.parse(n[0]);
  z(b,r)=>b>0?b&n==b&511?"win":z(b>>9,n&b==0?"lose":r):r;
  print(z(0x9224893c01c01e2254,"cat"));
}

1

CJam, 39 38 36 caratteri

"ᔔꉚ굌궽渒䗠脯뗠㰍㔚귇籾〳㎪䬔⹴쪳儏⃒ꈯ琉"2G#b129b:c~

Questo è un codice convertito di base per

q3/_z__Wf%s4%\s4%]`:Q3'o*#"win"{Q'x3*#"lose""cat"?}?

che è lungo 52 caratteri.

L'input è semplicemente la rappresentazione in forma di stringa della scheda che parte da sinistra in alto, procedendo riga per riga. Per esempio:

oxooxooox

che si traduce in un winoutput. O

oxooxoxox

che si traduce in un catoutput, ecc.

Il codice fa semplicemente le tre cose seguenti:

  • q3/_ - Dividi la stringa in parti di 3, cioè per riga
  • _z - Copia l'array per riga e traspone nell'array per colonna.
  • __Wf%s4%- Invertire ogni riga e ottenere la diagonale da sinistra a destra. Questa è la diagonale secondaria della tavola.
  • \s4% - Ottieni la diagonale principale del tabellone
  • ]` - Avvolgere tutto nell'array e stringere l'array.

Ora abbiamo tutti i possibili gruppi di 3 dal tabellone. Controlliamo semplicemente l'esistenza di "ooo" e "xxx" per determinare il risultato.

Provalo online qui


1

GNU sed, 25 byte

Se l'input è una rappresentazione ridondante del tabellone con viste separate per colonne, file e diagonali, come pure usato in altre risposte, sed è molto adatto per controllare lo stato finale del gioco con il minor numero di byte.

Formato di input: xxx ooo xxx xox xox xox xox xox (stato della scheda tratto dalla domanda del PO)

/xxx/cwin
/ooo/close
ccat

Se il formato di input non è ridondante ( xxx ooo xxx), il codice sed qui sopra funziona solo se anteposto dalla riga seguente, rendendo il programma lungo 96 byte (con il rflag necessario conteggiato).

s/(.)(.)(.) (.)(.)(.) (.)(.)(.)/& \1\4\7 \2\5\8 \3\6\9 \1\5\9 \3\5\7/

1

Bash: 208 caratteri

y(){ tr '01' '10'<<<$@;}
f(){ x=$[($1&$2&$3)|($1&$5&$9)|($1&$4&$7)|($2&$5&$8)|($3&$5&$7)|($3&$6&$9)|($4&$5&$6)|($7&$8&$9)]; }
f $@;w=$x
f $(y $@)
([ $x -eq 1 ]&&echo lose)||([ $w -eq 1 ]&&echo win)||echo cat

Eseguire bash tictactoe.sh 0 1 0 1 0 1 1 0 1

Ispirato da questa risposta .


0

VB.net

Con l'esempio fornire è codificato come il seguente modello di bit

q  = &B_100101_100110_011010 ' 00 Empty, 01 = O, 10 = X

Ora possiamo determinare il risultato (o il vincitore) procedendo come segue.

Dim g = {21, 1344, 86016, 66576, 16644, 4161, 65379, 4368}
Dim w = If(g.Any(Function(p)(q And p)=p),"Lose",If(g.Any(Function(p)(q And p*2)=p*2),"Win","Cat"))

0

J - 97 byte

Bene, l'approccio più semplice disponibile. L'input viene considerato come 111222333, dove i numeri rappresentano le righe. Leggi da sinistra a destra. Il giocatore è xe il nemico è o. I quadrati vuoti possono essere qualsiasi cosa tranne xo o.

f=:(cat`lose>@{~'ooo'&c)`('win'"_)@.('xxx'&c=:+./@(r,(r|:),((r=:-:"1)(0 4 8&{,:2 4 6&{)@,))3 3&$)

Esempi: (NB è un commento)

   f 'xoxxoxxox' NB. Victory from first and last column.
win
   f 'oxxxooxxx' NB. Victory from last row.
win
   f 'ooxxoxxxo' NB. The example case, lost to a diagonal.
lose
   f 'xxooxxxoo' NB. Nobody won.
cat
   f 'xoo xx ox' NB. Victory from diagonal.
win

Ungolfed code una spiegazione

row   =: -:"1                        Checks if victory can be achieved from any row.
col   =: -:"1 |:                     Checks if victory can be achieved from any column.
diag  =: -:"1 (0 4 8&{ ,: 2 4 6&{)@, Checks if victory can be achieved from diagonals.
check =: +./@(row,col,diag) 3 3&$    Checks all of the above and OR's them.

f     =: (cat`lose >@{~ 'ooo'&check)`('win'"_)@.('xxx'&check)
Check if you have won ........................@.('xxx'&check)
 If yes, return 'win' .............. ('win'"_)
 If not                   (cat`lose >@{~ 'ooo'&check)
  Check if enemy won ................... 'ooo'&check
   If yes, return 'lose'   ---`lose >@{~
   If not, return 'cat'    cat`---- >@{~

0

Python 2, 120 byte

b=0b101001110
l=[448,56,7,292,146,73,273,84]
print(['Win'for w in l if w&b==w]+['Lose'for w in l if w&~b==w]+['Cat'])[0]

O Python, 115 byte dalla shell Python (2 o 3):

b=0b101001110;l=[448,56,7,292,146,73,273,84];(['Win'for w in l if w&b==w]+['Lose'for w in l if w&~b==w]+['Cat'])[0]

La variabile board è impostata sul formato binario descritto nella domanda: 1per X, 0per O, da sinistra a destra, dall'alto verso il basso. In questo caso, 101001110rappresenta

XOX
OOX
XXO

Che porta all'output: Cat


Qual è il formato di input?
Seequ,

0

Python ( 73 62 caratteri)

L'input è costituito da quattro stringhe minuscole che rappresentano quattro viste distinte della stessa scheda, tutte concatenate in un'unica stringa: per riga, per colonna, diagonale destra, diagonale sinistra.

AGGIORNARE

Grazie a the Rare per averlo sottolineato con un buon contro-esempio! Ogni vista del tabellone, insieme a ciascun segmento (riga o colonna) all'interno di un tabellone, deve essere separato da un carattere che non è né una "x" o una "o" in modo che la struttura del tabellone venga preservata anche dopo la concatenazione. I bordi attorno a ciascuna vista della lavagna saranno parentesi quadre ("[" e "]") e il separatore tra righe / colonne sarà un carattere di pipe "|".

Questo semplifica l'algoritmo: basta cercare rispettivamente "xxx" o "ooo" per una vittoria o una perdita. Altrimenti è un pareggio (gatto).

Ad esempio la scheda (lettura da sinistra a destra, dall'alto verso il basso) ...

X | X | X X | O | X O | X | O

... è rappresentato come "[xxx | xox | oxo]" (per righe) + "[xxo | xox | xxo]" (per colonne) + "[xoo]" (diag destro) + [xoo] "(sinistro diag) = "[xxx | xox | oxo] [xxo | xox | xxo] [xoo] [xoo]".

Questa affermazione Python stampa il risultato del gioco dato la variabile s come input:

print 'win' if 'xxx' in s else 'lose' if 'ooo' in s else 'cat'

Funziona a bordo OXX XOO XOX(dovrebbe essere un gatto)?
Seequ,

No ... no non lo fa. Buona pesca! Immagino che la mia soluzione fosse un po 'troppo semplice ... Oops!
bob

Non posso dire che questo tipo di soluzione non mi sia passato per la testa. :)
seequ,

0

Haskell (69 caratteri)

i x=take 4$(x>>=(\y->case y of{'7'->"win";'0'->"lose";_->""}))++"cat"

Questo richiede lo stesso input descritto da questa risposta . Più specificamente, l'input è di 8 valori ottali, che descrivono il valore binario di ogni riga, colonna e diagonale. Il codice fa "vincere" ogni istanza di 7, ogni "0" perde ogni istanza e rimuove tutto il resto. Quindi aggiunge "cat" alla fine e prende i primi 4 caratteri dal risultato.

Ci saranno 4 possibili risposte: "perdi", "gatto", "vinci" seguito da una "l" e "vinci" seguito da una "c", che le regole non proibiscono :)

Esempio di utilizzo:

i "65153806" --outputs "lose"

0

J: 83

(;:'lose cat win'){::~>:*(-&(+/@:(*./"1)@;@(;((<0 1)&|:&.>@(;|.)(,<)|:)))-.)3 3$'x'=

Uso: basta aggiungere una serie di x e o e guardare il lavoro magico. per esempio. 'Xxxoooxxx'.

Il verbo interno (+/@:(*./"1)@;@(;((<0 1)&|:&.>@(;|.)(,<)|:)))fondamentalmente racchiude la matrice binaria originale, con la trasposizione inscatolata insieme alle 2 diagonali. Questi risultati vengono rasi insieme; le somme di riga vengono prese per determinare le vincite e quindi sommate. più lontano chiamerò questo verbo Inner.

Per trovare il vincitore, la differenza dei punteggi tra le matrici binarie normali e inverse viene presa dal gancio (-&Inner -.).

Il resto del codice crea semplicemente gli output e seleziona quello giusto.


0

JavaScript, 133 , 114 caratteri

r = '/(1){3}|(1.{3}){2}1|(1.{4}){2}1|(1\|.1.\|1)/';alert(i.match(r)?'WIN':i.match(r.replace(/1/g,0))?'LOSS':'CAT')

L'input i è una semplice stringa con delimitatori per le righe, ad es100|001|100

Modifica: aggiornato il mio metodo per sostituire gli 1 nella regex con zero per verificare il caso di perdita.


Puoi rimuovere gli spazi intorno =e le virgolette attorno al regex letterale. Inoltre, 1...un personaggio è più corto di 1.{3}.
nyuszika7h

1
r.test(i)è anche un personaggio più corto di i.match(r).
nyuszika7h

0

J - 56 (26?) Char

All'input viene assegnata una matrice 3x3 di nove caratteri, poiché J può supportarlo come tipo di dati, LOL.

(win`lose`cat{::~xxx`ooo<./@i.<"1,<"1@|:,2 7{</.,</.@|.)

Esempi:

   NB. 4 equivalent ways to input the example board
   (3 3 $ 'xxoxoxoox') ; (_3 ]\ 'xxoxoxoox') ; ('xxo','xox',:'oox') ; (];._1 '|xxo|xox|oox')
+---+---+---+---+
|xxo|xxo|xxo|xxo|
|xox|xox|xox|xox|
|oox|oox|oox|oox|
+---+---+---+---+
   (win`lose`cat{::~xxx`ooo<./@i.<"1,<"1@|:,2 7{</.,</.@|.) 3 3 $ 'xxoxoxoox'
lose
   wlc =: (win`lose`cat{::~xxx`ooo<./@i.<"1,<"1@|:,2 7{</.,</.@|.)
   wlc (3 3 $ 'xoxoxooxo')
cat
   wlc (3 3 $ 'xxxoooxxx')
win

Se ci è permesso la codifica Golfscriptish di cifre ottali che rappresentano in modo ridondante lo stato di ogni riga, colonna e diagonale, allora sono solo 26 caratteri:

   win`lose`cat{::~7 0<./@i.] 6 5 1 6 4 3 5 0
lose
   f=:win`lose`cat{::~7 0<./@i.]
   f  7 0 7 5 5 5 5 5
win

0

T-SQL (2012), 110

select max(iif(@&m=0,'lose',iif(@&m=m,'win','cat')))from(VALUES(292),(146),(73),(448),(56),(7),(273),(84))z(m)

L'input è un numero esadecimale. Questa è praticamente una traduzione della soluzione ruby ​​in T-SQL piuttosto carina e ordinata.


0

Javascript 1.6, 71 caratteri

Sto assumendo l'input come un array gameche contiene ogni riga, ogni colonna e ogni diag come una stringa di 3 caratteri. Simile alla risposta di Bob , ma è disponibile in una matrice, non come una stringa concatenata.

alert(game.indexOf("xxx")>=0?"win":game.indexOf("ooo")>=0?"lose":"cat")

EDIT @ nyuszika7h 's commento (67 caratteri)

alert(~game.indexOf("xxx")?"win":~game.indexOf("ooo")?"lose":"cat")

Puoi usare ~game.indexOf("xxx")invece di game.indexOf("xxx")>=0, lo stesso per l'altro.
nyuszika7h

0

Java 7, 260 byte

String c(int[]s){int a[]=new int[8],x=0,y;for(;x<3;x++){for(y=0;y<3;a[x]+=s[x*3+y++]);for(y=0;y<3;a[x+3]+=s[y++%3]);}for(x=0;x<9;y=s[x],a[6]+=x%4<1?y:0;a[7]+=x%2<1&x>0&x++<8?y:0);x=0;for(int i:a)if(i>2)return"win";for(int i:a)if(i<1)return"loose";return"cat";}

Casi non testati e test:

Provalo qui.

class M{
  static String c(int[] s){
    int a[] = new int[8],
        x = 0,
        y;
    for(; x < 3; x++){
      for(y = 0; y < 3; a[x] += s[x * 3 + y++]);
      for (y = 0; y < 3; a[x + 3] += s[y++ % 3]);
    }
    for(x = 0; x < 9; y = s[x],
                      a[6] += x % 4 < 1
                               ? y
                               : 0,
                      a[7] += x % 2 < 1 & x > 0 & x++ < 8
                               ? y
                               : 0);
    x = 0;
    for(int i : a){
      if(i > 2){
        return "win";
      }
    }
    for(int i : a){
      if(i < 1){
        return "loose";
      }
    }
    return "cat";
  }

  public static void main(String[] a){
    /*  xxo
        xox
        oox  */
    System.out.println(c(new int[]{ 1, 1, 0, 1, 0, 1, 0, 0, 1 }));
    /*  xxx
        ooo
        xxx  */
    System.out.println(c(new int[]{ 1, 1, 1, 0, 0, 0, 1, 1, 1 }));
    /*  xxo
        oox
        xox  */
    System.out.println(c(new int[]{ 1, 1, 0, 0, 0, 1, 1, 0, 1 }));
  }
}

Produzione:

loose
win
cat

0

APL (NARS), 69 caratteri, 138 byte

{w←3 3⍴⍵⋄x←(+/1 1⍉⊖w),(+/1 1⍉w),(+⌿w),+/w⋄3∊x:'win'⋄0∊x:'lose'⋄'cat'}

L'input dovrebbe essere una matrice 3x3 o una matrice lineare di 9 elementi che può essere solo 1 (per X) e 0 (per O), il risultato sarà "cat" se nessuno vince, "perde" se O vince, "win "se X vince. Non c'è controllo per una scheda non valida o l'input è un array con meno di 9 elementi o più o controlla ogni elemento <2.

Come commento: convertirà l'input in una matrice 3x3 e costruirà un array chiamato "x" dove gli elementi sono la somma di ogni riga di riga e diagonale.

Alcuni test vedono esempi mostrati da altri:

  f←{w←3 3⍴⍵⋄x←(+/1 1⍉⊖w),(+/1 1⍉w),(+⌿w),+/w⋄3∊x:'win'⋄0∊x:'lose'⋄'cat'}
  f 1 2 3
win
  f 0 0 0
lose
  f 1 0 1  1 0 1  1 0 1
win
  f 0 1 1  1 0 0  1 1 1
win
  f 0 0 1  1 0 1  1 1 0
lose
  f 1 1 0  0 1 1  1 0 0
cat
  f 1 1 0  0 1 0  0 0 1
win
  f 1 1 0  1 0 1  0 0 1
lose
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.