Фон
Алиса и Боб играют в игру под названием « построить двоичное слово» . Для того, чтобы играть в эту игру, вы фиксируете длину n >= 0
, набор G
из длина- n
двоичных слов называется поставленная цель , и длина- n
строку , t
содержащую буквы A
и B
, называемый порядок оборота . Игра длится по n
очереди, и на ходу i
игрок, определенный с помощью, t[i]
выбирает немного w[i]
. Когда игра заканчивается, игроки смотрят на двоичное слово, которое w
они создали. Если это слово найдено в поставленной цели G
, Алиса выигрывает игру; в противном случае Боб выигрывает.
Например, давайте исправить n = 4
, G = [0001,1011,0010]
и t = AABA
. Алиса получает первый ход, и она выбирает w[0] = 0
. Второй ход тоже за Алисой, и она выбирает w[1] = 0
. У Боба третий ход, и он выбирает w[2] = 0
. На последнем повороте Алиса выбирает w[3] = 1
. Полученное слово, 0001
находится в G
, так что Алиса выигрывает игру.
Теперь, если бы Боб выбрал w[2] = 1
, Алиса могла бы выбрать w[3] = 0
в своем последнем повороте и все же выиграть. Это означает, что Алиса может выиграть игру независимо от того, как играет Боб. В этой ситуации у Алисы есть выигрышная стратегия . Эту стратегию можно представить в виде помеченного двоичного дерева, которое ветвится на уровнях, соответствующих поворотам Боба, и каждая ветвь которых содержит слово из G
:
A A B A
-0-0-0-1
\
1-0
Алиса играет, просто следуя веткам на своем ходу; Независимо от того, какую ветвь выберет Боб, в конечном итоге победит Алиса.
вход
Вам дается в качестве входных данных длина n
, а в G
качестве (возможно, пустой) список строк длины n
.
Выход
Ваш вывод - это список ордеров хода, для которых у Алисы есть выигрышная стратегия, что эквивалентно существованию бинарного дерева, как описано выше. Порядок ордеров хода не имеет значения, но дублирование запрещено.
Подробные правила
Вы можете написать полную программу или функцию. В случае программы вы можете выбрать разделитель для ввода и вывода, но он должен быть одинаковым для обоих. Самый короткий счетчик байтов выигрывает, и стандартные лазейки запрещены.
Тестовые случаи
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]
Интересный факт
Количество порядков хода на выходе всегда равно количеству слов в наборе целей.
11101
дважды; забавный факт все еще имеет место для наборов. Згарб, может вход содержит повторяющиеся элементы, или это ошибка?Ответы:
Дьялог АПЛ, 59 байт
{(a≡,⊂⍬)∨0=⍴a←∪⍵:a⋄(∇h/t)(('A',¨∪),'B',¨∩)∇(~h←⊃¨a)/t←1↓¨a}
Тот же алгоритм, что и в решении @ xnor.
источник
Python, 132
Пример выполнения:
Это всего лишь игра в гольф, в основном, чтобы показать алгоритм. Входами и выходами являются наборы строк. Python, похоже, не обладает необходимыми возможностями для компактного выражения частей, поэтому было бы здорово, если бы кто-то написал это на более подходящем языке.
Вот как рекурсия может быть выражена математически. К сожалению, в PPCG по-прежнему отсутствует математический рендеринг, поэтому мне придется использовать блоки кода.
Объектами интереса являются наборы строк. Позвольте
|
представить набор союза и&
представлять пересечение множества.Если
c
это символ, пустьc#S
представляет добавление символаc
ко всем строкам вS
. И наоборот, пусть сокращениеc\S
будет строкой на один символ корочеS
следующего за начальным символомc
, например,0\{001,010,110,111} = {01,10}
.Мы можем уникально разделить набор строк
S
с01
символами по их первому символу.Затем мы можем выразить искомую функцию
f
следующим образом, с базовыми падежами в первых двух строках и рекурсивным банком в последней строке:Обратите внимание, что нам не нужно использовать длину
n
.Почему это работает? Давайте подумаем о строках ходов, которые позволят Алисе победить за набор струн
S
.Если первым персонажем является
A
Алиса, она может выбрать первый ход («0» или «1»), позволяя ей решить проблему доS0
илиS1
. Итак, теперь оставшаяся строка перемещения должна быть хотя бы в одном изf(S0)
илиf(S1)
, следовательно, мы берем их объединение|
.Точно так же, если первый символ «B», Боб выбирает, и он выбирает худший для Алисы, поэтому оставшаяся строка движения должна быть в пересечении (
&
).Базовые случаи просто проверяют,
S
пусто или нет в конце. Если мы отслеживаем длину строкn
, вычитая 1 каждый раз, когда мы повторяем, вместо этого можно записать основы:Рекурсивное решение также объясняет забавный факт того
f(S)
же размера, что иS
. Это верно для базовых случаев и для индуктивного случаяу нас есть
источник
TypeError: 'int' object is not subscriptable
. У вас есть ссылка на работающую программу? Я просто вставил его и запустилprint f([0001,1011,0010],4)
f({'000','001','010','011','100','101','110','111'},3)
. Вы получаете ошибку таким образом?print f(['0001','1011','0010'],4)
n
независимо от параметров, это будетn=len(S[0])if S!=[]else 0