Contexte
Alice et Bob jouent à un jeu appelé construire un mot binaire . Pour jouer au jeu, vous fixez une longueur n >= 0
, un ensemble G
de n
mots binaires de longueur appelés le jeu d'objectifs , et une n
chaîne de longueur t
contenant les lettres A
et B
, appelée l' ordre du tour . Le jeu dure des n
tours, et au tour i
, le joueur défini par t[i]
sélectionne un peu w[i]
. Une fois le jeu terminé, les joueurs regardent le mot binaire w
qu'ils ont construit. Si ce mot est trouvé dans l'objectif fixé G
, Alice gagne la partie; sinon, Bob gagne.
Par exemple, nous allons fixer n = 4
, G = [0001,1011,0010]
et t = AABA
. Alice obtient le premier tour et elle choisit w[0] = 0
. Le deuxième tour est aussi celui d'Alice, et elle choisit w[1] = 0
. Bob a le troisième tour, et il choisit w[2] = 0
. Au dernier tour, Alice choisit w[3] = 1
. Le mot résultant,, 0001
se trouve dans G
, donc Alice gagne la partie.
Maintenant, si Bob avait choisi w[2] = 1
, Alice aurait pu choisir w[3] = 0
dans son dernier tour, et toujours gagner. Cela signifie qu'Alice peut gagner le jeu, peu importe la façon dont Bob joue. Dans cette situation, Alice a une stratégie gagnante . Cette stratégie peut être visualisée comme un arbre binaire étiqueté, qui se ramifie aux niveaux correspondant aux tours de Bob, et dont chaque branche contient un mot de G
:
A A B A
-0-0-0-1
\
1-0
Alice joue en suivant simplement les branches à son tour; quelle que soit la branche choisie par Bob, Alice finit par gagner.
Contribution
On vous donne en entrée la longueur n
, et l'ensemble G
comme une liste (éventuellement vide) de chaînes de longueur n
.
Production
Votre sortie est la liste des ordres de tour pour lesquels Alice a une stratégie gagnante, ce qui équivaut à l'existence d'un arbre binaire comme décrit ci-dessus. L'ordre des ordres de tour n'a pas d'importance, mais les doublons sont interdits.
Règles détaillées
Vous pouvez écrire un programme complet ou une fonction. Dans le cas d'un programme, vous pouvez choisir le délimiteur pour l'entrée et la sortie, mais il doit être le même pour les deux. Le nombre d'octets le plus court l'emporte et les failles standard sont interdites.
Cas de test
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]
Fait amusant
Le nombre d'ordres de tour dans la sortie est toujours égal au nombre de mots dans l'objectif fixé.
11101
deux fois; le fait amusant tient toujours pour les ensembles. Zgarb, l'entrée peut-elle contenir des éléments répétés, ou était-ce une erreur?Réponses:
Dyalog APL, 59 octets
{(a≡,⊂⍬)∨0=⍴a←∪⍵:a⋄(∇h/t)(('A',¨∪),'B',¨∩)∇(~h←⊃¨a)/t←1↓¨a}
Même algorithme que dans la solution @ xnor.
la source
Python, 132
Exemple d'exécution:
Ce n'est qu'une sorte de golf, principalement pour montrer l'algorithme. Les entrées et sorties sont des ensembles de chaînes. Python ne semble pas avoir les bonnes fonctionnalités pour exprimer des parties de cela de manière compacte, donc ce serait cool si quelqu'un écrivait cela dans un langage mieux adapté.
Voici comment la récursivité peut être exprimée mathématiquement. Malheureusement, PPCG manque toujours de rendu mathématique, donc je vais devoir utiliser des blocs de code.
Les objets d'intérêt sont des ensembles de chaînes. Soit
|
representer l'union set et&
representer l'intersection set.Si
c
est un caractère, laissezc#S
represent précéder le caractèrec
de toutes les chaînes de caractèresS
. Inversement, que la contractionc\S
soit les chaînes d'un caractère plus courtesS
qui suivent le caractère initialc
, par exemple0\{001,010,110,111} = {01,10}
.Nous pouvons diviser de façon unique un ensemble de chaînes
S
avec des caractères01
par leur premier caractère.Ensuite, nous pouvons exprimer la fonction souhaitée
f
comme suit, avec les cas de base dans les deux premières lignes et la boîte récursive dans la dernière ligne:Notez que nous n'avons pas besoin d'utiliser la longueur
n
.Pourquoi ça marche? Penchons-nous sur les chaînes de déplacement qui permettent à Alice de gagner pour un ensemble de chaînes
S
.Si le premier personnage est
A
, Alice peut choisir le premier coup ('0' ou '1'), lui laissant choisir de réduire le problème àS0
ouS1
. Alors maintenant , le mouvement chaîne restante doit être dans au moins l' un desf(S0)
ouf(S1)
, d' où nous prenons leur union|
.De même, si le premier caractère est 'B', Bob arrive à choisir, et il choisira le pire pour Alice, donc la chaîne de déplacement restante doit être dans l'intersection (
&
).Les cas de base vérifient simplement si
S
est vide ou non à la fin. Si nous suivons la longueur des chaînesn
, en soustrayant 1 à chaque récurrence, les bases peuvent être écrites à la place:La solution récursive explique également le fait amusant qui
f(S)
a la même taille queS
. C'est vrai pour les cas de base et pour le cas inductifon a
la source
TypeError: 'int' object is not subscriptable
. Avez-vous un lien vers un programme exécutable? Je viens de le coller et de l'print f([0001,1011,0010],4)
f({'000','001','010','011','100','101','110','111'},3)
. Obtenez-vous une erreur de cette façon?print f(['0001','1011','0010'],4)
n
indépendamment des paramètres, ce seraitn=len(S[0])if S!=[]else 0