C250- Une grille de Kakuro [**** à la main]
On rappelle qu’une grille de Kakuro, comme la grille G donnée ci-après, comporte des cases vides qu’il s’agit de remplir avec des chiffres compris entre 1 et 9 à partir de définitions qui sont des nombres entiers figurant sur le bord gauche et sur le bord supérieur selon les règles suivantes :
- chacun des nombres qui figurent à l’intérieur de la grille et sont lus en ligne puis en colonne ne contient jamais deux fois le même chiffre,
- la somme des chiffres d'un nombre est donnée par sa définition qui figure soit sur le bord gauche pour les nombres lus en ligne soit sur le bord supérieur pour les nombres lus en colonne .
c₁ c₂ c₃ c₄
l₁ a b c
l₂ d e f g
l₃ h i j
Grille G
La grille G comporte sept définitions, trois en ligne (l₁, l₂ et l₃) et quatre en colonne (c₁ à c₄).
Comme l₁ + l₂ + l₃ = c₁ + c₂ + c₃ + c₄, l’omission d’une seule définition ne change rien à la résolution de la grille. A l’inverse l’omission de deux définitions peut augmenter le nombre de solutions possibles.
Le casse-tête de ce mois consiste à trouver sept entiers l₁, l₂ ,l₃, c₁,c₂,c₃,c₄ de manière que : - la solution de la grille G est unique avec ces sept définitions,
- il y au moins une solution supplémentaire quand on omet deux définitions quelconques parmi les sept (soit C(7,2) = 21 combinaisons possibles).
Solution proposée par Daniel Collignon
Théoriquement il y a 9*8*8*7*7*7*6*6*6*6 = 256 048 128 grilles distinctes sans tenir compte des définitions. Elles correspondent à 11 525 225 définitions différentes.
Parmi celles-ci, 536 764 donnent une unique grille. Pour des raisons de temps de calcul, j'ai généré une table des 21 cas à partir du sous-ensemble des définitions donnant une grille unique, correspondant à 6 266 348 définitions partielles différentes. J’ai obtenu alors une liste de 4 480 grilles solutions du problème qui donnent une évaluation a minima du nombre total de solutions possibles.
En annexe le programme en langage Python.
Parmi toutes ces solutions, je propose la grille-mère G à solution unique suivante avec ses définitions l₁,l₂,l₃,c₁, c₂, c₃ et c₄.
4 7 14 9 7
11 16
dont la solution est :
4 7 14 9 7 1 2 4
11 1 2 3 5
16 3 4 9
avec les 21 solutions dérivées (en caractères rouges, les définitions obtenues après omission des deux définitions de la grille-mère G):
Annexe : programme en Python Principe :
- création d'un dictionnaire dict1 synthétisant les définitions et leur fréquence de toutes les grilles possibles (force brute)
- l'ensemble ens1 contient alors celles donnant une grille unique
- création d'un dictionnaire dict2 synthétisant les définitions partielles de ces grilles uniques et leur fréquence
- l'ensemble ens2 contient alors les grilles uniques dont toutes les définitions partielles
donnent au moins une autre grille
#Kakuro de la forme
#Xabc
#defg
#hijX
#où X désigne une case noire import time
tps1 = time.clock()
chiffres = set(range(1, 10)) dict1 = {}
dict2 = {}
ens1 = set() ens2 = set()
for a in chiffres:
for b in chiffres - {a}:
for c in chiffres - {a, b}:
l1 = a + b + c
for g in chiffres - {c}:
for f in chiffres - {b, g}:
for e in chiffres - {a, f, g}:
for d in chiffres - {e, f, g}:
l2= d + e + f + g for j in chiffres - {b, f}:
for i in chiffres - {a, e, j}:
for h in chiffres - {d, i, j}:
l3 = h + i + j c1 = d + h c2 = a + e + i c3 = b + f + j c4 = c + g
ch = l1, l2, l3, c1, c2, c3, c4
if ch in dict1:
dict1[ch] += 1 else:
dict1[ch] = 1 print(len(dict1))
for defi, nombre in dict1.items():
if nombre == 1:
ens1.add(defi) print(len(ens1)) for defi in ens1:
l1, l2, l3, c1, c2, c3, c4=defi ch1="","",l3,c1,c2,c3,c4
ch2="",l2,"",c1,c2,c3,c4 ch3="",l2,l3,"",c2,c3,c4 ch4="",l2,l3,c1,"",c3,c4 ch5="",l2,l3,c1,c2,"",c4 ch6="",l2,l3,c1,c2,c3,""
ch7=l1,"","",c1,c2,c3,c4 ch8=l1,"",l3,"",c2,c3,c4 ch9=l1,"",l3,c1,"",c3,c4 ch10=l1,"",l3,c1,c2,"",c4
ch11=l1,"",l3,c1,c2,c3,""
ch12=l1,l2,"","",c2,c3,c4 ch13=l1,l2,"",c1,"",c3,c4 ch14=l1,l2,"",c1,c2,"",c4 ch15=l1,l2,"",c1,c2,c3,""
ch16=l1,l2,l3,"","",c3,c4 ch17=l1,l2,l3,"",c2,"",c4 ch18=l1,l2,l3,"",c2,c3,""
ch19=l1,l2,l3,c1,"","",c4 ch20=l1,l2,l3,c1,"",c3,""
ch21=l1,l2,l3,c1,c2,"",""
if ch1 in dict2:
dict2[ch1]+=1 else:
dict2[ch1]=1 if ch2 in dict2:
dict2[ch2]+=1 else:
dict2[ch2]=1 if ch3 in dict2:
dict2[ch3]+=1 else:
dict2[ch3]=1 if ch4 in dict2:
dict2[ch4]+=1 else:
dict2[ch4]=1 if ch5 in dict2:
dict2[ch5]+=1 else:
dict2[ch5]=1 if ch6 in dict2:
dict2[ch6]+=1 else:
dict2[ch6]=1 if ch7 in dict2:
dict2[ch7]+=1 else:
dict2[ch7]=1 if ch8 in dict2:
dict2[ch8]+=1 else:
dict2[ch8]=1 if ch9 in dict2:
dict2[ch9]+=1 else:
dict2[ch9]=1 if ch10 in dict2:
dict2[ch10]+=1 else:
dict2[ch10]=1 if ch11 in dict2:
dict2[ch11]+=1 else:
dict2[ch11]=1 if ch12 in dict2:
dict2[ch12]+=1 else:
dict2[ch12]=1 if ch13 in dict2:
dict2[ch13]+=1
else:
dict2[ch13]=1 if ch14 in dict2:
dict2[ch14]+=1 else:
dict2[ch14]=1 if ch15 in dict2:
dict2[ch15]+=1 else:
dict2[ch15]=1 if ch16 in dict2:
dict2[ch16]+=1 else:
dict2[ch16]=1 if ch17 in dict2:
dict2[ch17]+=1 else:
dict2[ch17]=1 if ch18 in dict2:
dict2[ch18]+=1 else:
dict2[ch18]=1 if ch19 in dict2:
dict2[ch19]+=1 else:
dict2[ch19]=1 if ch20 in dict2:
dict2[ch20]+=1 else:
dict2[ch20]=1 if ch21 in dict2:
dict2[ch21]+=1 else:
dict2[ch21]=1 print(len(dict2)) for defi in ens1:
l1, l2, l3, c1, c2, c3, c4=defi ch1="","",l3,c1,c2,c3,c4
ch2="",l2,"",c1,c2,c3,c4 ch3="",l2,l3,"",c2,c3,c4 ch4="",l2,l3,c1,"",c3,c4 ch5="",l2,l3,c1,c2,"",c4 ch6="",l2,l3,c1,c2,c3,""
ch7=l1,"","",c1,c2,c3,c4 ch8=l1,"",l3,"",c2,c3,c4 ch9=l1,"",l3,c1,"",c3,c4 ch10=l1,"",l3,c1,c2,"",c4 ch11=l1,"",l3,c1,c2,c3,""
ch12=l1,l2,"","",c2,c3,c4 ch13=l1,l2,"",c1,"",c3,c4 ch14=l1,l2,"",c1,c2,"",c4 ch15=l1,l2,"",c1,c2,c3,""
ch16=l1,l2,l3,"","",c3,c4 ch17=l1,l2,l3,"",c2,"",c4 ch18=l1,l2,l3,"",c2,c3,""
ch19=l1,l2,l3,c1,"","",c4 ch20=l1,l2,l3,c1,"",c3,""
ch21=l1,l2,l3,c1,c2,"",""
if dict2[ch1]>1 and dict2[ch2]>1 and dict2[ch3]>1 and dict2[ch4]>1 and dict2[ch5]>1 and dict2[ch6]>1 and dict2[ch7]>1 and dict2[ch8]>1 and dict2[ch9]>1 and dict2[ch10]>1 and dict2[ch11]>1 and dict2[ch12]>1 and dict2[ch13]>1 and dict2[ch14]>1 and dict2[ch15]>1 and dict2[ch16]>1 and dict2[ch17]>1 and dict2[ch18]>1 and dict2[ch19]>1 and dict2[ch20]>1 and dict2[ch21]>1:
ens2.add(defi) print(len(ens2)) for defi in ens2:
print(defi)
tps2 = time.clock() print(tps2 – tps1)