Il dizionario della punta di Tic Tac


17

Una TicTacToepartita può essere rappresentata da una stringa che indica la sequenza di posizioni mentre i giocatori fanno la loro mossa.

0 1 2
3 4 5
6 7 8

Supponiamo che Xsuona sempre per primo.

Quindi una stringa di "012345678" indica il gioco

XOX
OXO
XOX

Nota, il gioco è già vinto quando il giocatore Xsegna 6, a quel punto la partita termina, garantendo una vittoria a X. (cioè, ignora le mosse rimanenti una volta che un giocatore vince)

La tua sfida (codice) è quella di stampare tutti i giochi (ordine ordinato) e i suoi risultati.

Il formato

<movesequence>:<result>\n

per esempio:

012345678:X
012345687:X
012345768:X
...

Indicare Xper il 1 ° giocatore vincente, Oper il secondo giocatore e Dper i sorteggi.

Ci saranno 9!(362880) giochi.

Ecco alcuni dati per verificare i risultati.

'X' Wins: 212256 
'O' Wins: 104544 
Draws : 46080 

Questo è un codegolf e il tempo di esecuzione dovrebbe essere entro un minuto. Divertiti!

EDIT: rimossi i dettagli in eccesso e basta stamparli stdout. Non è necessario creare un file.


2
Sto ottenendo numeri diversi qui: 212256 vittorie per X, 104544 vittorie per O e 46080 pareggi (e Wikipedia sembra essere d'accordo con me ).
Ventero,

@Ventero, ricontrollerò, ma non vedo alcun riferimento a quei numeri sulla pagina.
via

@Ventero, hai ragione, modificherò quella parte. pubblicherò presto il md5sum.
via

1
La risposta di Ruby non è la più breve, quindi non dovrebbe essere la risposta accettata in base ai tuoi criteri di punteggio (code-golf).
mbomb007,

Risposte:


3

Ruby 1.9, 201 caratteri

r=*[*l=0..8,0,3,6,1,4,7,2,5,8,0,4,8,2,4,6].each_slice(3)
w=->a{r.any?{|b|b&a==b}}
[*l].permutation(9){|a|u=[[],[]];i=-1
u[i%2]<<a[i+=1]while !((x=w[u[1]])||o=w[u[0]])&&i<8
puts a*""+":#{x ??X:o ??O:?D}"}

Finalmente leggermente golfato. Ci vogliono circa 45 secondi per completare qui.

  • Modifica: (268 -> 249) Scrive su stdout anziché su un file
  • Modifica: (249 -> 222) Non pre-riempire l'array con le mosse di ogni giocatore.
  • Modifica: (222 -> 208) Modo più breve per scoprire se un giocatore ha vinto
  • Modifica: (208 -> 213) Torna a 213, la soluzione precedente era troppo lenta.
  • Modifica: (213 -> 201) Alcuni riarrangiamenti, spazio vuoto rimosso

Ho modificato un po 'la domanda, non è necessario creare un file ora, basta stamparlo.
via

4

J, 124 caratteri

((],~':',~1":[){&'DOX'@(</+2*>/)@:(<./"1)@:(((2{m/.@|.),(2{m/.),m"1,>./)"2)@(<:@(>:%2|]),:(%(2|>:)))@(3 3$]))"1((i.!9)A.i.9)

Conta X, vinci e pareggi.

Il debug è stato un po 'doloroso. :)


3

Haskell, 224 222 caratteri

import Data.List
p=sort.permutations
a(e:_:z)=e:a z;a z=z
[c,d]%(e:z)|any((`elem`words"012 345 678 036 147 258 048 246").take 3).p.a.reverse$e=c|1<3=[d,c]%z;_%[]='D'
main=putStr$p['0'..'8']>>=(\s->s++':':"OX"%inits s:"\n")

Purtroppo, la permutationsfunzione da Data.Listnon produce permutazioni in ordine lessografico. Quindi ho dovuto spendere 6 personaggi per questo tipo.


2

APL (139)

Questo probabilmente può essere abbreviato di più, ma è stato abbastanza difficile così com'è. Che ci crediate o no, funziona in circa 45 secondi sul mio computer (escluso il tempo necessario per l'output di tutto, quando l'output sullo schermo).

↑{⊃,/(,/⍕¨⍵-1),':',{1∊T←↑{∨/↑{⍵∘{⍵≡⍵∧⍺}¨↓⍉(9⍴2)⊤⎕UCS'㗀㐇㔤㑉㔑㑔'}¨↓(M∘.≥M)∧[2]M∊⍵}¨↓⍉5 2⍴0,⍨⍵:'XO'[1+</+/T]⋄'D'}⍵}¨↓{1≥⍴⍵:↑,↓⍵⋄↑⍪/⍵,∘∇¨⍵∘~¨⍵}M←⍳9

Spiegazione:

  • M←⍳9: Memorizza in M ​​i numeri da 1 a 9. Internamente, questo programma utilizza 1..9 anziché 0..8.
  • {... }: una funzione per ottenere tutte le permutazioni:
    • 1≥⍴⍵:↑,↓⍵: se la lunghezza è inferiore o uguale a 1, restituisce l'argomento come matrice.
    • ⋄↑⍪/⍵,∘∇¨⍵∘~¨⍵: in caso contrario, rimuovi ogni personaggio da , ottieni le permutazioni e aggiungi nuovamente il personaggio.
  • ¨↓: per ogni permutazione ...
  • {... }: una funzione che dà il vincitore per quella permutazione:
    • ⊃,/(,/⍕¨⍵-1),':',{...}⍵ : ottieni la permutazione come una stringa, con tutti i numeri diminuiti di 1 (per ottenere l'output 0..8 richiesto anziché 1..9), seguito da due punti, seguito dal carattere che indica il vincitore:
      • ⍉5 2⍴0,⍨⍵: separa le mosse di X dalle mosse di O. Poiché O ha una mossa in meno di X, quello spazio è riempito da 0, che è inutilizzato e quindi non influenza il risultato.
      • {... }¨↓: sia per la X board che per la O board, esegui la seguente funzione che determina se c'è una vittoria in uno dei nove timestep:
        • (M∘.≥M)∧[2]M∊⍵: Genera un bitboard dai numeri di movimento e andquesto bitboard con i bittring 100000000, 110000000... 111111111per ottenere lo stato del board in ciascuno dei nove momenti nel tempo.
        • {...}¨↓ : per ognuno di questi, eseguire la seguente funzione:
          • ⍉(9⍴2)⊤⎕UCS'㗀㐇㔤㑉㔑㑔': ottieni i bitboard per ogni possibile situazione vincente
          • ⍵∘{⍵≡⍵∧⍺}¨↓: andogni stato vincente con l'attuale bitboard e verificare se detto stato vincente è ancora lì
        • ∨/↑: orquesti insieme, dando se c'è una vittoria su questo bitboard
      • 1∊T←↑: crea una matrice 9x2, con i 9 timestep X sulla prima riga e i 9 timestep O sulla seconda riga. Memorizza questo in T. Se c'è un 1 in questa matrice, qualcuno ha vinto.
      • :'XO'[1+</+/T]: Se qualcuno ha vinto, dai 'X' o 'O' a seconda di chi è 1stato il primo.
      • ⋄'D': Se nessuno ha vinto, dai 'D'.
  • : creane una matrice in modo che siano visualizzate ciascuna su una riga separata.

1

Python Ungolfed

from itertools import*
r=range
W=[[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]]
def c(B):
    for i in r(8):
                if B[W[i][0]]==B[W[i][1]]==B[W[i][2]]:
                        return 1
        return 0

for i in permutations('012345678',9):
    B=[]
    for j in r(9):
        B.append(-(j+1))
    k=0
    F=1
    for j in r(9):
        k=[1,0][k]
        B[int(i[j])]=k
        if c(B):
            F=0
            break
    print "".join(i),':',[['0','X'][k],'D'][F]

non è necessario il secondo parametro inpermutations
st0le

3
Per favore golf il tuo programma.
mbomb007,

1

C ++ Ungolfed

#include<iostream>
using namespace std;
#include<algorithm>

int check(int B[])
{
        for (int i=0;i<3;i++)
                if ((B[3*i]==B[3*i+1]&&B[3*i]==B[3*i+2]) || (B[i]==B[i+3]&&B[i]==B[i+6]))
                        return 1;
        if ((B[2]==B[4]&&B[2]==B[6]) || (B[0]==B[4]&&B[0]==B[8]))
                return 1;
        return 0;               
}
int main()
{
        char c[11]="012345678";
        int B[9],i,j;
        do{
                for (i=0;i<9;i++)B[i]=-(i+1);
                for (i=0,j=1;i<9;i++,j=j?0:1)
                {
                        B[c[i]-'0']=j;
                        if (check(B))
                                break;
                }
                printf("%s:%c\n",c,i<9?j?'X':'O':'D');
        }while (next_permutation(c,c+9));
}

4
Per favore golf il tuo programma.
mbomb007,

1

Python 2.7 (237)

from itertools import*
for z in permutations('012345678'):
 k,F=0,[9]*9
 for h in z:
    F[int(h)]=k=1-k
    if any(sum(a)in(0,3)for a in(F[:3],F[3:6],F[6:],F[::3],F[1::3],F[2::3],F[::4],F[2:8:2])):break
 else:k=2
 print"".join(z)+':','OXD'[k]
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.