STAGE IREM Qu`est-ce qu`un takuzu

Transcription

STAGE IREM Qu`est-ce qu`un takuzu
Université de Bordeaux
16-18 Février 2014/2015
IREM de Bordeaux
STAGE IREM
2- Les takuzus
Les takuzus (ou “bineros” ) sont des casse-têtes analogues aux sudokus, que l’on trouve dans les
revues de “jeux” ou de “sport cérébral” . Le professeur Senizuku voudrait arriver à les résoudre
de facon automatique. Il a déjà quelques idées de départ, mais il faut que vous l’aidiez.
Qu’est-ce qu’un takuzu ?
Un takuzu est une grille carrée, dont chaque case est soit remplie par un 0 ou par un symbole
1 ou bien est vide.
Une solution est un remplissage des cases vides par des 0 et des 1 qui satisfait les conditions
suivantes :
C1 : chaque ligne et chaque colonne contient autant de 0 que de 1
C2 : dans chaque ligne et chaque colonne, il n’y pas plus de deux symboles 0 (ou 1) consécutifs
C3 : il n’ y pas deux lignes (ni deux colonnes) identiques
Exercice 2.1 Résoudre “à la main” les takuzus (taz0,taz1,taz10) suivants :
0
1
1
1 1
0
0
0
1
0
0 1
1
1
1
0
0 1
1
1 1
0 0
1
1
1
0
0
1
0
1
1
0
1
1 1
0
1
0 0
0 0
1
1
0 0
1 1
0
En fait, un problème de takuzu bien posé est une grille incomplète qui ne peut être complétée
que d’une et une seule façon en une grille satisfaisant C1 et C2 et C3.
Exercice 2.2 Le takuzu taz2 suivant
1 0
0
taz3 :=
a-t-il une solution ? Est-il bien posé ? Soit
0
1
1
0
0
0
0
a-t-il une solution ? Est-il bien posé ?
0
1
0
Exercice 2.3 Arrivez-vous à résoudre les takuzus suivants (taz11,taz12,taz13) :
0
0 0
1
1
1 1
0
1 1
1
0
1
1
0
0
0
0
1
1
0
0 0
0
1
0
0
0
1
1
0 0
0
0
1
0 0
0
1
1
0
0
0
1
0
1
1
1
1
1
1
0
1 1
1
0
1
1
0
1
1
0
0
0
1
0
0
0
Représenter un takuzu
On propose de représenter un takuzu, en python , par une liste de listes.
# # r e n v o i e une grille a b s t r a i t e de takuzu avec LARG c o l o n n e s et HAUT lignes .
# # c ’ est un t a b l e a u de {0 ,1 None }
# #= liste des lignes du t a b l e a u
# # taz [ i ][ j ] est la case de la i - eme ligne et j - ieme c o l o n n e
def n e w t a k u z u ( LARG , HAUT ):
res =[[ None ]* LARG ]* HAUT
return res
Par exemple on définira les takuzus :
taz0 =[[1 ,1 , None ,0] ,[ None ,0 , None , None ] ,[ None , None ,0 , None ] ,[ None ,1 , None ,0]]
taz1 = n e w t a k u z u (4 ,4)
taz1 [0]=[0 ,1 ,None ,1]
taz1 [1]=[1 , None ,1 , None ]
taz1 [2]=[0 , None ,0 ,1]
taz1 [3]=[1 , None ,1 ,1]
Exercice 2.4 Ecrire une fonction ligne(i,taz) qui retourne la i-eme ligne de la grille taz.
Attention : le résultat renvoyé est une copie de cette ligne (et non l’adresse de la ligne de la
grille).
Exercice 2.5 Ecrire une fonction colonne(j,taz) qui retourne la j-eme colonne de la grille
taz.
Visualiser les takuzus
On souhaite voir les takuzus sur l’écran. On se dit qu’il suffit de transformer un takuzu en
image, puis d’utiliser la fonction Image.show().
Exercice 2.6 Ecrire une fonction grille_to_im(taz)qui prend en entrée une grille taz et
retourne une image qui visualise cette grille. (On représentera chacun des symboles 0,1,N one
par une couleur différente.
Tester votre fonction sur les takuzus taz0,taz1.
Exercice 2.7 Ecrire une fonction visu(taz) qui provoque la visualisation sur l’écran de la
grille taz.
2
Tester les takuzus
Exercice 2.8 Ecrire une fonction verifierl(ls) qui teste qu’une liste de 0,1 et N one est
“correcte” i.e. a au moins un prolongement qui satisfait C1 et C2.
Exercice 2.9 Ecrire une fonction complet(ls) qui teste qu’une liste est complète, i.e. que
chaque case est remplie par un 0 ou un 1.
Exercice 2.10 Ecrire une fonction complet_t(taz) qui teste qu’un takuzu est complet (i.e.
que chaque case est remplie par un 0 ou un 1.
Exercice 2.11 Ecrire une fonction verifier_tout(taz) qui teste que le takuzu taz satisfait
les conditions C1,C2,C3.
Résoudre les takuzus
On cherche à résoudre les takuzu en appliquant, tant que le takuzu n’ est pas complet, à
une région (i.e. une ligne ou une colonne) une tactique. Voici un exemple de tactique :
# # ls est une liste
# # r e n v o i e False si aucune t e n a i l l e dans ls
# # r e n v o i e [ valeur , a d r e s s e] si une t e n a i l l e i m p l i q u e d ’ a f f e c t e r valeur a cette a d
def t e n a i l l e( ls ):
L = len ( ls )
for i in range (L -2):
if ls [ i ]!= None and ls [ i ]== ls [ i +2] and ls [ i +1]== None :
return [1 - ls [ i ] ,i +1]
return False
Par exemple : >>>tenaille([0,1,None,1,None])
[0, 2] Voici un schéma général de fonction qui résout les takuzu, par application de tactiques.
# # prend en entree une grille de takuzu ( i n c o m p l e t e en g e n e r a l)
# # m o d i f i e cette grille
# # r e n v o i e True ssi elle r e u s s i t a c o m p l e t e r la grille ( False sinon )
def r e s o u d r e 1 ( taz ):
# on met dans une queue toutes les r e g i o n s a tester : lignes et c o l o n n e s
Q = queue ( l i s t e _ r e g i o n s ( taz ))
# on met dans Ltac une liste de t a c t i q u e s
Ltac =[ tenaille , bloc2 ,...]
while True :
region = Q . head ()
p r o g r e s= False
for i in range ( len ( Ltac )):
if not p r o g r e s:
p r o g r e s= aptaz ( Ltac [ i ] , region ,Q , taz )
# si le takuzu est rempli
if c o m p l e t _ t( taz ):
assert v e r i f i e r _ t o u t ( taz )
return True
# si toutes les t a c t i q u e s d e t e r m i n i s t e s ont echoue sur cette region
elif not p r o g r e s:
Q . pop ()
# plus d ’ espoir -> pas de s o l u t i o n
if Q . empty ():
return False
# espoir -> on c o n t i n u e
3
Exercice 2.12 Mettre au point des tactiques (tenir compte des bocs de longueur 2, du nombre
de 0 et de 1 déjà présents, etc ...)
On peut espérer résoudre les takuzu de niveau 1 par des tactiques simples.
En mettant au point des tactiques suffisamment évoluées on peut espérer résoudre les takuzus
de niveau 3.
Comment résoudre des takuzus de niveau arbitraire ? Intuitivement, lorsque aucune tactique
n’est applicable, on fait l’hypothèse que telle case (non encore remplie) aura la valeur 0 (ou 1),
puis on essaye de résoudre le nouveau takuzu ainsi défini.
Exercice 2.13 Mettre au point la fonction ci-dessous.
# # prend en entree une grille de takuzu ( i n c o m p l e t e en g e n e r a l)
# # une queue de r e g i o n s Q ( celles qui d o i v e n t etre t e s t e e s)
# # une liste de t a c t i q u e s Ltac ( chaque t a c t i q u e peut t r a i t e r une region )
# # m o d i f i e cette grille
# # r e n v o i e le nombre de s o l u t i o n s
# # l ’ etat final de la grille c o r r e s p o n d au choix l e x i c o g r a p h i q u e m e n t
# # m i n i m a l sur les h y p o t h e s e
def r e s o u d r e _ r e c ( Ltac ,Q , taz ):
Pouvez-résoudre taz13 maintenant ? est-il bien posé ?
Créer des takuzus
Pouvez-vous créer des takuzus de dimension 4 à la main ? Et de dimension 10 ? Comment
s’assurer qu’il est bien posé ?
Le takuzu taz12 est tiré de la revue Jeux-vacances 26, page 57, en bas à droite, en le réduisant
i.e. en remplacant le 1 en position (9, 0) dans cette revue par la case vide (taz12[9][0]=N one).
Si on le réduit encore en vidant la case d’indices (0, 1), obtient-on encore un takuzu bien-posé ?
Jusqu’où peut-on aller dans la réduction ?
Exercice 2.14 Peut-on tirer parti de ces remarques pour écrire une fonction fabriquer(taz),
qui prend en entrée un takuzu complet et retourne un takuzu dont l’unique solution est taz et
qui n’est pas trivial ...
Exercice 2.15 Ecrire une fonction extend_and_reduce(taz), qui prend en entrée une grille
peu remplie (en dimension 10, une vingtaine de cases ont une valeur) et retourne une grille qui
est un takuzu bien posé et irréductible (i.e. toute suppression de case le rend mal-posé).
Arrivez-vous à résoudre “à la main” les takuzus fabriqués par votre programme ? ?
4

Documents pareils