Tantangan
Diberi papan tic-tac-toe dalam format apa pun, tentukan apakah itu valid atau tidak. Jika papan dapat menjadi hasil dari permainan tic-tac-toe, maka itu valid. Misalnya, forum ini valid:
XOX OXO XOXSebaliknya, forum ini tidak valid:
XXX XXO OOO
Memasukkan
- Papan tic tac toe penuh (9/9) (hasilnya, bukan game).
Aturan
- Format input harus dapat menggambarkan semua 512 papan input yang mungkin. Itu harus ditentukan, bersama dengan instruksi untuk membuatnya jika tidak jelas / tidak jelas. Anda harus menyatakan tanda-tanda papan secara individual.
- Harus ada dua kemungkinan keluaran, satu untuk validitas dan satu untuk ketidakabsahan.
- Anda dapat menganggap papan tidak memiliki tempat kosong.
Uji kasus
Sah:
XOX OXO XOX XOX XOX OXO XOO OOX OXX OXO XOX OXO
Tidak valid:
XXX XXX XXX OOO OOO OOO XXX OOO XXX OOO OOX XXX XXO OXO OOX
Sedikit bantuan?
Papan dianggap sah (untuk tantangan ini) jika dan hanya jika dua syarat berikut berlaku:
- Ada 5 X dan 4 O, atau 4 X dan 5 O. Misalnya,
XXX OXO XXX
dianggap tidak valid, karena ada 7 X dan 2 Os. - Hanya pemain dengan 5 nilai yang menang, atau tidak ada yang menang. Sebagai contoh,
XXX OOO OOX
dianggap tidak valid, karena barisO
s atau barisX
s akan dibentuk terlebih dahulu. Kedua pemain tidak bisa mendapatkan giliran secara bersamaan.
Pemenang saat ini adalah ...
... jawaban Jelly ais523 , dengan 26 byte yang menakjubkan!
code-golf
decision-problem
tic-tac-toe
Erik the Outgolfer
sumber
sumber
O O O
X O X
X O X
, untuk menunjukkan bahwa pemain yang sama mungkin memiliki baris horizontal dan vertikal.Jawaban:
Jelly , 26 byte
Cobalah online!
Format input sedikit tidak biasa; itu adalah string yang mewakili papan, tetapi dengan baris baru Windows (carriage return diikuti oleh baris baru). Sebagai contoh
XXO\r\nOXO\r\nOOX
,. (Sebenarnya, string padding dua karakter di antara garis berfungsi, tetapi baris baru Windows jauh lebih dapat dipertahankan daripada opsi lainnya.)Ide dasarnya adalah kita mencari karakter yang muncul 4 kali dalam input, tetapi tidak memiliki tiga kejadian spasi secara merata dalam string asli. Dengan dua atau lebih karakter padding di antara garis-garis kisi 3 × 3, semua garis horizontal, vertikal, dan diagonal diberi spasi secara merata, tetapi tidak ada garis spasi merata lainnya yang dapat memiliki tiga elemen.
Penjelasan:
The
ð
danµ
s adalah pemisah rantai , yang membagi program ke dalam beberapa bagian yang masing-masing independen. Saya telah menggantinya dengan spasi di bawah ini, untuk membuat semuanya lebih jelas.Dengan kata lain, kami menemukan daftar karakter yang muncul tepat empat kali di input, dan membuat daftar yang terdiri dari tiga salinan dari masing-masing; kami menemukan daftar semua urutan yang ditempatkan secara merata di string asli; dan jika kita mengurangi yang kedua dari yang pertama, kita ingin hasilnya memiliki panjang 1 (yaitu seorang pemain bermain empat kali tetapi tidak menang). Perhatikan bahwa karena kita berada di kotak 3 × 3 dan setiap kotak penuh, mustahil bagi kedua pemain untuk bermain empat kali. Dalam Jelly, 1 benar, 0 adalah palsu, jadi kita tidak perlu melakukan hal khusus untuk mengubah daftar yang dihasilkan menjadi boolean. (Namun
µL
diperlukan, karena jika tidak keduanya“XXX”
dan“OOO”
akan menjadi nilai output yang mungkin benar, dan pertanyaannya mengharuskan semua papan yang valid memberikan output yang sama.)sumber
JavaScript (ES6),
8887 byteMengambil input sebagai string 9
0
dan1
karakter dan mengembalikan1
untuk valid,0
untuk tidak valid. Kami mengurutkan karakter ke dalam urutan. Jika tiga karakter tengah sekarang sama maka papan tidak valid karena ada terlalu banyak bagian. Kalau tidak, kami mengubah papan asli menjadi biner, membalik bit jika ada lebih0
dari1
s. Pada titik ini papan valid jika0
tidak memiliki garis tiga, jadi kami cukup menguji semua delapan garis melalui array bitmask. Sunting: Disimpan 1 byte berkat @ETHproductions.sumber
Python 3,
13112712510096 byteUntuk pendekatan algoritmik yang berbeda (dan yang akan sangat cocok untuk bahasa golf multi-byte ini dengan kompresi bawaan), daripada menghitung apakah papan tersebut valid, mari kita memiliki angka 512-bit di mana setiap bit mewakili apakah atau tidak papan tertentu valid atau tidak, dan meneruskan nilai biner yang mewakili papan. Selanjutnya, karena simetri, bagian kedua tabel dapat dihilangkan, bersama dengan sekelompok nol:
Nilai tes:
Diwakili sebagai nilai biner
0b111010111
, dan fungsi mengembalikan nilai bukan nol jika papan valid.sumber
a&(1<<b)
tidak perlu tanda kurung.if b>255:b=511-b
!if
.Batch, 140 byte
Mengambil input sebagai sembilan argumen baris perintah dan keluaran terpisah
1
untuk valid dan0
tidak valid. Bekerja dengan melacak berapa kali ia melihatO
garis ortogonalOOO
atauXXX
. Mudah Batch memungkinkan kita untuk melakukan bilangan bulat aritmatika secara tidak langsung, jadi kami tidak menambah%%l
tetapi beberapa variabel sebagai gantinya (meskipun kami hanya tertarik pada tiga variabel yang disebutkan). Kami kemudian perlu menguji apakahX
belum menang dan ada limaO
s atau yangO
belum menang dan ada empatO
s.sumber
Mathematica,
8275 byteTerima kasih kepada Martin Ender karena telah menghemat 7 byte!
Fungsi tanpa nama mengambil daftar bersarang 3x3 dari 1s dan 0s sebagai input dan keluaran
True
atauFalse
.Menggunakan beberapa fleksibilitas
Total
fungsi (di sini di-golft
): diberikan contoh arraye = { {1,2,3} , {4,5,6} , {7,8,9} }
, perintah init[e]
menjumlahkan tiga vektor (di sini menghasilkan{12,15,18}
); perintah init/@e
merangkum setiap sublist secara individual (di sini menghasilkan{6,15,24}
); dan perintah itue~t~2
merangkum semua sembilan elemen (di sini menghasilkan45
).Jadi pertama-tama kita menguji, dengan
3<(b=#~t~2)<6
, apakah jumlah total 1 adalah 4 atau 5; jika tidak kita keluar denganFalse
. Jika demikian, kita gunakanc=If[b>4,1-#,#]
untuk memaksa ada empat 1, bukan lima. Kemudian kita menghitung jumlah kolomt[c]
, jumlah barist/@c
, jumlah diagonal utamaTr@c
, dan jumlah diagonal yang berlawananTr@Reverse~c
, dan digunakan~FreeQ~3
untuk memeriksa yang3
gagal muncul pada tingkat mana pun dalam jumlah yang dihitung tersebut.Catatan samping yang mengasyikkan: tidak seperti kebanyakan penampilan di situs ini, di sini
Tr
tidak digunakan untuk menjumlahkan daftar satu dimensi tetapi sebenarnya digunakan sebagaimana dirancang — untuk menghitung jejak matriks dua dimensi!sumber
Pyth - 36 byte
Saya memasukkan diagas dan menggunakan dua terner sebagai gantinya.
Test Suite
sumber
JavaScript (ES6), 101 byte
Mengambil input sebagai topeng biner 9-bit di mana
X = 1
danO = 0
(MSB = sel kiri atas, LSB = sel kanan bawah).Uji kasus
Tampilkan cuplikan kode
sumber
Python 2,
1581321099291123 byteInput adalah daftar / tupel baris, masing-masing tiga tupel string, misalnya:
[('X', 'O', 'X'), ('O', 'X', 'O'), ('X', 'O', 'X')]
Menyimpan beberapa byte dengan mengabaikan diagonal per jawaban Maltysen, yang juga mempersingkat ekspresi berikut.Terima kasih @vaultah untuk menyimpan1718 byte.Memeriksa diagonal ternyata diperlukan, yang menghilangkan banyak penghematan di atas.
Coba di sini.
Penjelasan
f
adalah input rata untuk memotong.w
berisi karakter dengan urutan kemenangan.Hitung kemunculan setiap karakter yang menang, yang akan menjadi 0 jika
w
kosong atau 5 jikalen(w)
1. Jumlah 10 ketika keduanya memiliki urutan kemenangan tidak mungkin. Pemenang memiliki 5 berarti pecundang memiliki 4. Anda tidak dapat memiliki> 5 tanpa urutan kemenangan.sumber
lambda b:len({x[0]for x in b+zip(*b)if len(set(x))==1})<2and set(map(
b.count,'XO'))=={4,5}
menyimpan beberapa byte....and{4,5}==set(map(
b.count,'XO'))
menyimpan satu byte lagi.R,
8882 byteSemua kombinasi dari tiga bilangan bulat dari 1 hingga 9 yang berjumlah hingga 15 adalah baris / kolom / diagonal kotak yang ditunjukkan di bawah ini.
Fungsi mengambil input sebagai vektor boolean, T untuk "X", F untuk "O", yang merupakan representasi rata dari papan. NAMUN, ini disusun ulang sehingga indeks mereka sama dengan angka di dalam kotak, dalam urutan (2,7,6,9,5,1,4,3,8). Agar itu dapat dicapai dengan meratakan papan dengan cara normal, dan kemudian mengiris dengan c (6,1,8,7,5,3,2,9,4). Jadi ini
direpresentasikan sebagai:
yang mana:
Fungsi pertama menentukan apakah ada pemain dengan tepat empat tanda. Jika demikian, fungsi menggunakan fakta-hal-yang-menambahkan-ke-15 untuk menentukan apakah pemain itu memiliki tiga-dalam-baris (papan tidak valid jika pemain itu melakukannya).
Jika Anda ingin menggunakan papan yang rata secara konvensional sebagai input, kodenya akan terlihat seperti ini:
Saya baru dalam hal ini, saran akan sangat dihargai.
sumber
if()
sebagai gantinya:f=function(x)
jika(sum(x)%in%4:5,all(apply(combn(which(x==(sum(x)<5)),3),2,sum)!=15),F)
. Tidak diuji secara luas pikiran Anda. Backticks merusak kode, tapi itubacktick if backtick(
.x=scan();
jika(sum(x)%in%4:5,all(apply(combn(which(x==(sum(x)<5)),3),2,sum)!=15),F)
dan masukan sebagai1
dan0
. 82 byteJavaScript (ES6),
145139131127 byteInput sebagai string yang dipisahkan oleh spasi, seperti
"XOX OXO XOX"
. Output1
untuk papan tidak valid,0
untuk papan yang valid. Ini jelas bukan teknik terbaik, setidaknya tidak dengan JavaScript ...Ini pada dasarnya memeriksa apakah kedua penahanan berikut:
O
s, DANRegex adalah untuk memeriksa apakah suatu game telah diputuskan. Ini cocok dengan papan jika ada panjang berjalan tiga dari satu karakter dengan 0 (baris), 2 (diagonal kanan bawah), 3 (kolom), atau 4 karakter (diagonal kiri bawah) yang memisahkan masing-masing pasangan.
Cuplikan tes
Tampilkan cuplikan kode
sumber
Ruby,
104 9991 byteFormat input: string biner dari 9 simbol (0s dan 1s) mewakili papan, misalnya test case pertama adalah
101010101
. Pertama-tama konversikan ke nomor biner, periksa apakah popcount adalah 4 atau 5, jika 5 membalikkan angka sehingga kita selalu memiliki 4. Periksa apakah tiga dari mereka disejajarkan (masking dengan horisontal, vertikal, diagonal).TL; DR : Return false jika pemain dengan 4 nilai menang, benar sebaliknya.
Terima kasih Jordan atas komentarnya,
Saya tidak dapat mereproduksi string UTF-8 yang akan menghemat byte lain.
sumber
.select{...}[0]
dengan.find{...}
."8ǀĤITđ".unpack("U*")
(jika ada sesuatu yang hilang dalam terjemahan, string adalah hasil dari memanggilpack("U*")
array asli; itu 12 byte).any?
sebagai penggantinone?
, membalik output dan menyimpan seluruh byte seluruh?Perl 6 ,
10399 byteLambda yang menerima daftar daftar suka
(('X','O','X'), ('O','X','O'), ('X','O','X'))
, dan mengembalikan Bool.Ini berfungsi seperti ini:
c
. (Jika tidak ada tanda yang muncul tepat 5 kali, ini akan mengandung nilai falsy)c
itu benar, dan setiap baris yang menang adalah tipec
.sumber
PHP, 125 byte
Aku punya ide yang sama seperti Arnauld : papan ini berlaku jika ada 4 atau 5 bit menetapkan dan baik
X
atauO
atau tidak ada yang memiliki beruntun (tapi tidak keduanya).Untuk menghasilkan input dari bidang, ganti
X
dengan1
danO
dengan0
, gabungkan baris dan konversi biner ke desimal, berikan sebagai argumen baris perintah.cetakan
1
untuk valid; output kosong untuk tidak valid. Jalankan dengan-r
.kerusakan
sumber
Swift, 178 byte
sumber
ES6 (Javacript),
130,138, 117 byteEDIT:
Pendekatan lurus ekstrim. Mungkin bisa bermain golf lebih jauh.
Menerima input sebagai 9 argumen terpisah, 1es dan 0es
Argumen: 1-3 - baris pertama, 4-6 - baris kedua, 7-9 - baris ketiga.
Golf
Interaktif "Tempat Tidur Test"
sumber
[1,0,1,1,0,1,0,1,0]
(XOX XOX OXO
).a+b+c+d+e+f+g+H+i
alih-alihF.reduce((r,c)=>r+=c*1)
(pada saat itu Anda tidak perluF
) b) menulis.includes(C)
(dan lanjutkan ke nilai inlineC
)?OOO XXX OXO
gagal?