Kamus Tic Tac Toe

17

Sebuah TicTacToepermainan dapat diwakili oleh string yang menunjukkan urutan posisi saat para pemain bergerak.

0 1 2
3 4 5
6 7 8

Asumsikan Xselalu bermain dulu.

Jadi string "012345678" menunjukkan permainan

XOX
OXO
XOX

Perhatikan, permainan sudah dimenangkan ketika Pemain Xmenandai 6, pada saat itu permainan berakhir, memberikan kemenangan kepada X. (yaitu, abaikan gerakan yang tersisa setelah pemain menang)

Tantangan Anda (kode) adalah untuk mencetak semua game (urutan diurutkan) dan hasilnya.

Format

<movesequence>:<result>\n

misalnya:

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

Dinotasikan Xuntuk pemain pertama yang menang, Ountuk pemain kedua, dan Duntuk Draws.

Akan ada 9!(362880) game.

Berikut adalah beberapa data untuk memverifikasi hasil Anda.

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

Ini adalah codegolf, dan runtime harus dalam satu menit. Selamat bersenang-senang!

EDIT: Menghapus rincian berlebih, dan cukup mencetaknya stdout. Tidak perlu membuat file.

st0le
sumber
2
Saya mendapatkan nomor yang berbeda di sini: 212256 menang untuk X, 104544 menang untuk O dan 46080 menarik (dan Wikipedia tampaknya setuju dengan saya ).
Ventero
@Ventero, saya akan periksa kembali, tapi saya tidak melihat referensi ke nomor-nomor di halaman.
st0le
@Ventero, Anda benar, saya akan mengedit bagian itu. akan segera memposting md5sum.
st0le
1
Jawaban Ruby bukan yang terpendek, jadi itu seharusnya bukan jawaban yang diterima sesuai dengan kriteria penilaian Anda (kode-golf).
mbomb007

Jawaban:

3

Ruby 1.9, 201 karakter

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}"}

Sejauh ini golf sedikit. Butuh sekitar 45 detik untuk menyelesaikannya di sini.

  • Sunting: (268 -> 249) Tulis ke stdout bukan file
  • Sunting: (249 -> 222) Jangan pra-isi array dengan gerakan masing-masing pemain.
  • Sunting: (222 -> 208) Cara lebih pendek untuk mengetahui apakah seorang pemain menang
  • Sunting: (208 -> 213) Kembali ke 213, solusi sebelumnya terlalu lambat.
  • Sunting: (213 -> 201) Beberapa penataan ulang, menghapus spasi putih
Ventero
sumber
Saya sedikit mengedit pertanyaan, Anda tidak perlu membuat file sekarang, cukup cetak saja.
st0le
4

J, 124 karakter

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

X win, O win dan Draw counts lihat.

Agak menyakitkan untuk di-debug. :)

randomra
sumber
3

Haskell, 224 222 karakter

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")

Sayangnya, permutationsfungsi dari Data.Listtidak menghasilkan permutasi dalam urutan leksografis. Jadi saya harus mengeluarkan 6 karakter semacam itu.

MtnViewMark
sumber
2

APL (139)

Ini mungkin dapat dipersingkat lebih, tapi itu cukup sulit. Percaya atau tidak, itu berjalan dalam waktu sekitar 45 detik di komputer saya (tidak termasuk waktu yang dibutuhkan untuk output semuanya, ketika output ke layar).

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

Penjelasan:

  • M←⍳9: Simpan dalam M angka dari 1 hingga 9. Secara internal, program ini menggunakan 1..9 bukannya 0..8.
  • {... }: fungsi untuk mendapatkan semua permutasi:
    • 1≥⍴⍵:↑,↓⍵: jika panjangnya lebih kecil atau sama dengan 1, kembalikan argumen sebagai matriks.
    • ⋄↑⍪/⍵,∘∇¨⍵∘~¨⍵: jika tidak, hapus setiap karakter dari , dapatkan permutasi dari itu, dan tambahkan kembali karakter.
  • ¨↓: untuk setiap permutasi ...
  • {... }: fungsi yang memberikan pemenang untuk permutasi itu:
    • ⊃,/(,/⍕¨⍵-1),':',{... }⍵: dapatkan permutasi sebagai string, dengan semua angka dikurangi 1 (untuk mendapatkan output 0..8 yang diperlukan, bukan 1..9), diikuti oleh titik dua, diikuti oleh karakter yang menunjukkan pemenang:
      • ⍉5 2⍴0,⍨⍵: pisahkan gerakan oleh X dari gerakan oleh O. Karena O memiliki satu gerakan kurang dari X, ruang itu diisi oleh 0, yang tidak digunakan dan tidak mempengaruhi hasilnya.
      • {... }¨↓: untuk papan X dan papan O, jalankan fungsi berikut yang menentukan apakah ada kemenangan di salah satu dari sembilan catatan waktu:
        • (M∘.≥M)∧[2]M∊⍵: Hasilkan bitboard dari nomor bergerak, dan andbitboard ini dengan bitstrings 100000000, 110000000... 111111111untuk mendapatkan status papan pada masing-masing dari sembilan momen dalam waktu.
        • {... }¨↓: untuk masing-masing ini, jalankan fungsi berikut:
          • ⍉(9⍴2)⊤⎕UCS'㗀㐇㔤㑉㔑㑔': dapatkan bitboard untuk setiap situasi kemenangan yang memungkinkan
          • ⍵∘{⍵≡⍵∧⍺}¨↓: andsetiap negara pemenang dengan bitboard saat ini dan periksa apakah negara yang menang masih ada
        • ∨/↑: orini bersama, memberi apakah ada kemenangan di papan bit ini
      • 1∊T←↑: buat matriks 9x2, dengan 9 X-timesteps di baris pertama dan 9 O-timesteps di baris kedua. Simpan ini dalam T. Jika ada 1 dalam matriks ini, seseorang telah menang.
      • :'XO'[1+</+/T]: Jika seseorang menang, berikan 'X' atau 'O' tergantung pada siapa 1yang pertama.
      • ⋄'D': Jika tidak ada yang menang, berikan 'D'.
  • : buat matriks dari ini sehingga masing-masing ditampilkan pada baris terpisah.
marinus
sumber
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]
fR0DDY
sumber
Anda tidak perlu param kedua dipermutations
st0le
3
Silakan golf program Anda.
mbomb007
1

C ++ Tidak Disatukan

#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));
}
fR0DDY
sumber
4
Silakan golf program Anda.
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]
Daniel
sumber