Latar Belakang
Alice dan Bob memainkan permainan yang disebut membangun kata biner . Untuk memainkan game ini, Anda memperbaiki panjang n >= 0
, satu set G
dari panjang- n
kata biner disebut tujuan set , dan panjang- n
string yang t
berisi surat-surat A
dan B
, yang disebut urutan giliran . Permainan berlangsung n
bergantian, dan pada gilirannya i
, pemain ditentukan oleh t[i]
memilih sedikit w[i]
. Ketika permainan berakhir, para pemain melihat kata biner yang w
telah mereka buat. Jika kata ini ditemukan di set tujuan G
, Alice memenangkan permainan; kalau tidak, Bob yang menang.
Sebagai contoh, mari kita memperbaiki n = 4
, G = [0001,1011,0010]
dan t = AABA
. Alice mendapat giliran pertama, dan dia memilih w[0] = 0
. Giliran kedua juga milik Alice, dan dia memilih w[1] = 0
. Bob mendapat giliran ketiga, dan dia memilih w[2] = 0
. Pada belokan terakhir, Alice memilih w[3] = 1
. Kata yang dihasilkan,, 0001
ditemukan di G
, jadi Alice memenangkan permainan.
Sekarang, jika Bob memilih w[2] = 1
, Alice bisa memilih w[3] = 0
pada giliran terakhirnya, dan masih menang. Ini berarti bahwa Alice dapat memenangkan permainan tidak peduli bagaimana Bob bermain. Dalam situasi ini, Alice memiliki strategi kemenangan . Strategi ini dapat divisualisasikan sebagai pohon biner berlabel, yang bercabang pada tingkat yang sesuai dengan belokan Bob, dan yang setiap cabangnya berisi kata dari G
:
A A B A
-0-0-0-1
\
1-0
Alice bermain dengan hanya mengikuti cabang pada gilirannya; tidak peduli cabang mana yang dipilih Bob, Alice akhirnya menang.
Memasukkan
Anda diberikan sebagai input panjang n
, dan set G
sebagai daftar panjang string (mungkin kosong)n
.
Keluaran
Output Anda adalah daftar turn order yang mana Alice memiliki strategi kemenangan, yang setara dengan keberadaan pohon biner seperti dijelaskan di atas. Urutan pesanan belokan tidak masalah, tetapi duplikat dilarang.
Aturan rinci
Anda dapat menulis program atau fungsi lengkap. Dalam hal suatu program, Anda dapat memilih pembatas untuk input dan output, tetapi harus sama untuk keduanya. Hitungan byte terpendek menang, dan celah standar tidak diizinkan.
Uji Kasus
3 [] -> []
3 [000,001,010,011,100,101,110,111] -> [AAA,AAB,ABA,ABB,BAA,BAB,BBA,BBB]
4 [0001,1011,0010] -> [AAAA,BAAA,AABA]
4 [0001,1011,0010,0110,1111,0000] -> [AAAA,BAAA,ABAA,BBAA,AABA,AAAB]
5 [00011,00110,00111,11110,00001,11101,10101,01010,00010] -> [AAAAA,BAAAA,ABAAA,BBAAA,AABAA,AAABA,BAABA,AAAAB,AABAB]
Fakta Menarik
Jumlah pesanan belokan dalam output selalu sama dengan jumlah kata dalam set tujuan.
11101
dua kali; fakta menyenangkan masih berlaku untuk set. Zgarb, dapatkah input berisi elemen berulang, atau apakah ini kesalahan?Jawaban:
Dyalog APL, 59 byte
{(a≡,⊂⍬)∨0=⍴a←∪⍵:a⋄(∇h/t)(('A',¨∪),'B',¨∩)∇(~h←⊃¨a)/t←1↓¨a}
Algoritma yang sama seperti pada solusi @ xnor.
sumber
Python, 132
Contoh dijalankan:
Ini hanya semacam golf, kebanyakan untuk menunjukkan algoritme. Input dan output adalah serangkaian string. Python tampaknya tidak memiliki fitur yang tepat untuk mengekspresikan bagian-bagian ini secara kompak, jadi akan lebih keren jika seseorang menulis ini dalam bahasa yang lebih cocok.
Inilah cara rekursi dapat diekspresikan secara matematis. Sayangnya, PPCG masih kekurangan rendering matematika, jadi saya harus menggunakan blok kode.
Objek yang menarik adalah set string. Biarkan
|
mewakili set union dan&
mewakili set persimpangan.Jika
c
karakter, biarkanc#S
mewakili karakter yang mengawalic
dengan semua string diS
. Sebaliknya, biarkan kontraksic\S
menjadi string lebih pendek satu karakterS
yang mengikuti karakter awalc
, misalnya0\{001,010,110,111} = {01,10}
,.Kita dapat secara unik memisahkan serangkaian string
S
dengan karakter01
berdasarkan karakter pertama mereka.Kemudian, kita dapat mengekspresikan fungsi yang diinginkan
f
sebagai berikut, dengan kasus basis di dua baris pertama dan kaleng rekursif di baris terakhir:Perhatikan bahwa kita tidak perlu menggunakan panjangnya
n
.Mengapa ini bekerja? Mari kita pikirkan tentang string-string yang memungkinkan Alice menang untuk serangkaian string
S
.Jika karakter pertama adalah
A
, Alice dapat memilih langkah pertama ('0' atau '1'), membiarkannya memilih untuk mengurangi masalah menjadiS0
atauS1
. Jadi sekarang string-pindah yang tersisa harus dalam setidaknya satuf(S0)
atauf(S1)
, karenanya kita mengambil penyatuan mereka|
.Demikian pula, jika karakter pertama adalah 'B', Bob dapat memilih, dan ia akan memilih yang lebih buruk untuk Alice, sehingga string-string yang tersisa harus berada di persimpangan (
&
).Kasing dasar hanya memeriksa apakah
S
kosong atau tidak pada akhirnya. Jika kita melacak panjang stringn
, dengan mengurangi 1 setiap kali kita berulang, basisnya dapat ditulis:Solusi rekursif juga menjelaskan fakta menyenangkan yang
f(S)
memiliki ukuran yang samaS
. Itu benar untuk kasus dasar, dan untuk kasus induktifkita punya
sumber
TypeError: 'int' object is not subscriptable
. Apakah Anda memiliki tautan ke program yang dapat dijalankan? Saya baru saja menempel dan menjalankannya denganprint f([0001,1011,0010],4)
f({'000','001','010','011','100','101','110','111'},3)
. Apakah Anda mendapatkan kesalahan dengan cara ini?print f(['0001','1011','0010'],4)
n
tergantung pada parameternyan=len(S[0])if S!=[]else 0