tło
Alice i Bob grają w grę o nazwie binarne słowo . Aby zagrać w grę, ustalamy długość n >= 0
, zestaw G
długości n
dwójkowych słów zwanych zestawem bramek oraz n
ciąg długości t
zawierający litery A
i B
nazywany porządkiem tury . Gra trwa przez n
tury, a na turę i
gracz określony przez t[i]
wybiera trochę w[i]
. Po zakończeniu gry gracze patrzą na binarne słowo w
, które skonstruowali. Jeśli to słowo zostanie znalezione w zestawie bramek G
, Alice wygrywa grę; w przeciwnym razie Bob wygrywa.
Na przykład, powiedzmy, fix n = 4
, G = [0001,1011,0010]
i t = AABA
. Alice dostaje pierwszą turę, a ona wybiera w[0] = 0
. Druga tura należy również do Alicji, a ona wybiera w[1] = 0
. Bob ma trzecią turę i wybiera w[2] = 0
. W ostatniej turze Alice wybiera w[3] = 1
. Wynikowe słowo, 0001
znajduje się w G
, więc Alice wygrywa.
Teraz, gdyby Bob wybrał w[2] = 1
, Alice mogłaby wybrać w[3] = 0
w swojej ostatniej turze i nadal wygrywać. Oznacza to, że Alice może wygrać grę bez względu na to, jak gra Bob. W tej sytuacji Alice ma zwycięską strategię . Strategię tę można zwizualizować jako oznaczone drzewo binarne, które rozgałęzia się na poziomach odpowiadających zwrotom Boba i którego każda gałąź zawiera słowo z G
:
A A B A
-0-0-0-1
\
1-0
Alice gra po prostu śledząc gałęzie w swojej turze; bez względu na to, którą gałąź wybierze Bob, Alice w końcu wygrywa.
Wejście
Jako dane wejściowe podano długość n
, a zestaw G
jako (być może pustą) listę ciągów długości n
.
Wynik
Twój wynik to lista rozkazów tury, dla których Alice ma strategię wygrywającą, co jest równoważne z istnieniem drzewa binarnego, jak opisano powyżej. Kolejność rozkazów tury nie ma znaczenia, ale duplikaty są zabronione.
Szczegółowe zasady
Możesz napisać pełny program lub funkcję. W przypadku programu możesz wybrać separator dla wejścia i wyjścia, ale musi być taki sam dla obu. Wygrywa najkrótsza liczba bajtów, a standardowe luki są niedozwolone.
Przypadki testowe
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]
Śmieszny fakt
Liczba zleceń skrętu na wyjściu jest zawsze równa liczbie słów w zestawie celów.
11101
dwa razy; zabawny fakt wciąż obowiązuje dla zestawów. Zgarb, czy dane wejściowe mogą zawierać powtarzające się elementy, czy był to błąd?Odpowiedzi:
Dyalog APL, 59 bajtów
{(a≡,⊂⍬)∨0=⍴a←∪⍵:a⋄(∇h/t)(('A',¨∪),'B',¨∩)∇(~h←⊃¨a)/t←1↓¨a}
Ten sam algorytm jak w rozwiązaniu @ xnor.
źródło
Python, 132
Przykładowy przebieg:
Jest to tylko rodzaj gry w golfa, głównie w celu pokazania algorytmu. Dane wejściowe i wyjściowe są zestawami ciągów. Python nie wydaje się mieć odpowiednich funkcji do wyrażania części tego zwięźle, więc byłoby fajnie, gdyby ktoś napisał to w lepiej dopasowanym języku.
Oto jak rekurencję można wyrazić matematycznie. Niestety PPCG wciąż nie ma renderowania matematycznego, więc będę musiał użyć bloków kodu.
Przedmiotem zainteresowania są zestawy ciągów znaków. Niech
|
reprezentuje zestaw unii i&
reprezentuje zestaw przecięcia.Jeśli
c
jest znakiem, niechc#S
reprezentuje wstawianie znakuc
do wszystkich łańcuchów wS
. I odwrotnie, niech skurczc\S
będzie krótszym o jeden znak ciągiemS
następującego po znaku początkowymc
, np0\{001,010,110,111} = {01,10}
.Możemy jednoznacznie podzielić zestaw ciągów
S
znaków01
ze znakami według ich pierwszej postaci.Następnie możemy wyrazić pożądaną funkcję
f
w następujący sposób, z przypadkami bazowymi w pierwszych dwóch wierszach, a rekurencyjną w ostatnim wierszu:Pamiętaj, że nie musimy używać długości
n
.Dlaczego to działa? Zastanówmy się nad ciągami ruchów, które pozwoliły Alice wygrać dla zestawu ciągów
S
.Jeśli pierwszą postacią jest
A
, Alice może wybrać pierwszy ruch („0” lub „1”), pozwalając jej zredukować problem doS0
lubS1
. Tak więc teraz pozostały ciąg ruchów musi znajdować się w co najmniej jednymf(S0)
lubf(S1)
, dlatego bierzemy ich związek|
.Podobnie, jeśli pierwszą postacią jest „B”, Bob może wybrać, a on wybierze gorszą dla Alice, więc pozostały ciąg ruchu musi znajdować się na przecięciu (
&
).Podstawy po prostu sprawdzają, czy
S
na końcu są puste, czy nie. Jeśli śledzimy długość ciągówn
, odejmując 1 za każdym razem, gdy się powtarzamy, zamiast tego można zapisać zasady:Rozwiązanie rekurencyjne wyjaśnia również zabawny fakt, który
f(S)
ma taki sam rozmiar jakS
. Dotyczy to przypadków podstawowych i przypadku indukcyjnegomamy
źródło
TypeError: 'int' object is not subscriptable
. Czy masz link do uruchamialnego programu? Właśnieprint f([0001,1011,0010],4)
f({'000','001','010','011','100','101','110','111'},3)
. Czy w ten sposób pojawia się błąd?print f(['0001','1011','0010'],4)
n
niezależnie od parametrów, byłoby ton=len(S[0])if S!=[]else 0