bdd | ||
images | ||
main1.py | ||
main2.py | ||
main3.py | ||
main4.py | ||
main5.py | ||
README.md | ||
sudoku_grid.py | ||
sudoku_mondrian.py | ||
sudoku_solver.py |
Autour des Sudoku
Diverses variations autour des Sudoku.
Licence
Tous les documents se trouvent ici avec la licence .
Description des fichiers
sudoku_grid.py
: module définissant une classeSudokuGrid
pour représenter les grilles de Sudoku.sudoku_solver.py
: module définissant une fonctionsolve
pour la résolution des grilles de Sudoku.sudoku_mondrian.py
: module permettant de produire des images représentant des grilles de Sudoku colorées « à la Mondrian ».main1.py
: script de résolution d'une grille décrite en argument sur la ligne de commande.main2.py
: script de résolution d'une grille contenue dans un fichier. Les solutions sont affichées dans le terminal.main3.py
: script de résolution de toutes les grilles contenues dans un fichier. Les solutions sont inscrites dans un fichier.main4.py
: script de résolution d'une grille décrite sur la ligne de commande, et qui produit une image représentant la recherche des solutions.main5.py
: scripy de résolution d'une grille décrite sur la ligne de commande, qui visualise le remplissage progressif de la grille.main6.py
: script produisant une représentation « à la Mondrian » d'une grille décrite sur la ligne de commande.bdd/sudokus.bdd
: un fichier texte contenant la description de 5000 grilles de Sudoku ayant toutes une seule solution.bdd/sudoku17.bdd
: un fichier texte contenant la description de 49151 grilles de Sudoku n'ayant que 17 cases remplis et ayant toutes une seule solution.
Solveurs de Sudoku
Exemples d'utilisation
Tous les exemples qui suivent s'exécutent dans un terminal de commandes (shell). Ils ont tous été testés sur une machine Linux (Debian). Dans les exemples qui suivent, le symbole $
désigne le prompt du terminal. Et les fichiers main?.py
sont supposés avoir le droit d'exécution (si ce n'est pas le cas, il faut remplacer ./main?.py
par python3 main?.py
.
Résoudre une grille de Sudoku décrite sur la ligne de commande
Avec le script main1.py
on peut résoudre toute grille de Sudoku décrite sur la ligne de commande.
Une grille de Sudoku est décrite sur la ligne de commande par une succession de 81 caractères compris entre 0
et 9
(0
pour une case vide). Les neuf premiers caractères représentent la première ligne de la grille, les neuf suivants la deuxième ligne, etc ...
À titre d'exemples, avec la grille
+-------+-------+-------+
| 9 . 6 | . 2 8 | . . 3 |
| . 4 . | 5 . . | . . 1 |
| . 8 . | 9 . . | . 4 . |
+-------+-------+-------+
| 6 . . | . . . | . 7 . |
| . . 8 | 2 . 6 | 9 . . |
| . 3 . | . . . | . . 5 |
+-------+-------+-------+
| . 5 . | . . 3 | . 6 . |
| 1 . . | . . 2 | . 8 . |
| 2 . . | 8 7 . | 5 . . |
+-------+-------+-------+
on obtient une seule solution
$ ./main1.py 906028003040500001080900040600000070008206900030000005050003060100002080200870500
Sudoku to solve
+-------+-------+-------+
| 9 . 6 | . 2 8 | . . 3 |
| . 4 . | 5 . . | . . 1 |
| . 8 . | 9 . . | . 4 . |
+-------+-------+-------+
| 6 . . | . . . | . 7 . |
| . . 8 | 2 . 6 | 9 . . |
| . 3 . | . . . | . . 5 |
+-------+-------+-------+
| . 5 . | . . 3 | . 6 . |
| 1 . . | . . 2 | . 8 . |
| 2 . . | 8 7 . | 5 . . |
+-------+-------+-------+
Number of solution(s): 1
--
Solution 1
+-------+-------+-------+
| 9 1 6 | 4 2 8 | 7 5 3 |
| 3 4 2 | 5 6 7 | 8 9 1 |
| 7 8 5 | 9 3 1 | 2 4 6 |
+-------+-------+-------+
| 6 2 9 | 3 4 5 | 1 7 8 |
| 5 7 8 | 2 1 6 | 9 3 4 |
| 4 3 1 | 7 8 9 | 6 2 5 |
+-------+-------+-------+
| 8 5 7 | 1 9 3 | 4 6 2 |
| 1 9 4 | 6 5 2 | 3 8 7 |
| 2 6 3 | 8 7 4 | 5 1 9 |
+-------+-------+-------+
--
Et avec la grille
+-------+-------+-------+
| 9 . 6 | . 2 8 | . . 3 |
| . 4 . | 5 . . | . . 1 |
| . 8 . | 9 . . | . 4 . |
+-------+-------+-------+
| 6 . . | . . . | . 7 . |
| . . 8 | 2 . 6 | 9 . . |
| . 3 . | . . . | . . 5 |
+-------+-------+-------+
| . 5 . | . . 3 | . 6 . |
| 1 . . | . . 2 | . 8 . |
| 2 . . | 8 7 . | . . . |
+-------+-------+-------+
on obtient deux solutions
$ ./main1.py 906028003040500001080900040600000070008206900030000005050003060100002080200870000
Sudoku to solve
+-------+-------+-------+
| 9 . 6 | . 2 8 | . . 3 |
| . 4 . | 5 . . | . . 1 |
| . 8 . | 9 . . | . 4 . |
+-------+-------+-------+
| 6 . . | . . . | . 7 . |
| . . 8 | 2 . 6 | 9 . . |
| . 3 . | . . . | . . 5 |
+-------+-------+-------+
| . 5 . | . . 3 | . 6 . |
| 1 . . | . . 2 | . 8 . |
| 2 . . | 8 7 . | . . . |
+-------+-------+-------+
Number of solution(s): 2
--
Solution 1
+-------+-------+-------+
| 9 1 6 | 4 2 8 | 7 5 3 |
| 3 4 2 | 5 6 7 | 8 9 1 |
| 7 8 5 | 9 3 1 | 2 4 6 |
+-------+-------+-------+
| 6 2 9 | 3 4 5 | 1 7 8 |
| 5 7 8 | 2 1 6 | 9 3 4 |
| 4 3 1 | 7 8 9 | 6 2 5 |
+-------+-------+-------+
| 8 5 7 | 1 9 3 | 4 6 2 |
| 1 9 4 | 6 5 2 | 3 8 7 |
| 2 6 3 | 8 7 4 | 5 1 9 |
+-------+-------+-------+
--
Solution 2
+-------+-------+-------+
| 9 1 6 | 4 2 8 | 7 5 3 |
| 3 4 2 | 5 6 7 | 8 9 1 |
| 7 8 5 | 9 3 1 | 2 4 6 |
+-------+-------+-------+
| 6 2 9 | 3 5 4 | 1 7 8 |
| 5 7 8 | 2 1 6 | 9 3 4 |
| 4 3 1 | 7 8 9 | 6 2 5 |
+-------+-------+-------+
| 8 5 7 | 1 9 3 | 4 6 2 |
| 1 9 3 | 6 4 2 | 5 8 7 |
| 2 6 4 | 8 7 5 | 3 1 9 |
+-------+-------+-------+
--
Enfin avec la grille
+-------+-------+-------+
| 9 7 6 | . 2 8 | . . 3 |
| . 4 . | 5 . . | . . 1 |
| . 8 . | 9 . . | . 4 . |
+-------+-------+-------+
| 6 . . | . . . | . 7 . |
| . . 8 | 2 . 6 | 9 . . |
| . 3 . | . . . | . . 5 |
+-------+-------+-------+
| . 5 . | . . 3 | . 6 . |
| 1 . . | . . 2 | . 8 . |
| 2 . . | 8 7 . | 5 . . |
+-------+-------+-------+
on n'obtient aucune solution
$ ./main1.py 976028003040500001080900040600000070008206900030000005050003060100002080200870500
Sudoku to solve
+-------+-------+-------+
| 9 7 6 | . 2 8 | . . 3 |
| . 4 . | 5 . . | . . 1 |
| . 8 . | 9 . . | . 4 . |
+-------+-------+-------+
| 6 . . | . . . | . 7 . |
| . . 8 | 2 . 6 | 9 . . |
| . 3 . | . . . | . . 5 |
+-------+-------+-------+
| . 5 . | . . 3 | . 6 . |
| 1 . . | . . 2 | . 8 . |
| 2 . . | 8 7 . | 5 . . |
+-------+-------+-------+
Number of solution(s): 0
--
Résoudre une grille de Sudoku décrite dans un fichier texte
Les grilles de Sudoku peuvent être décrites dans des fichiers texte. C'est le cas des deux fichiers bdd/sudokus.bdd
et bdd/sudoku17.bdd
qui contiennent chacun plusieurs milliers de grilles de Sudoku. Ces grilles sont décrites comme précédemment par des chaînes de 81 caractères compris entre 0
et 9
. Une description peut être précédée par un :
et dans ce cas les caractères qui précèdent sont ignorés.
Voici comment résoudre la première grille du fichier bdd/sudokus.bdd
$ ./main2.py bdd/sudokus.bdd 0
Sudoku to solve
+-------+-------+-------+
| 4 9 . | . . 1 | . . 7 |
| . . . | . 4 5 | . 3 . |
| 3 8 2 | 6 . . | . 5 . |
+-------+-------+-------+
| . . 3 | . 7 . | 4 . 1 |
| 8 . . | 9 . 2 | . . 5 |
| 9 . 7 | . 3 . | 6 . . |
+-------+-------+-------+
| . 3 . | . . 6 | 5 2 9 |
| . 2 . | 8 5 . | . . . |
| 5 . . | 7 . . | . 1 3 |
+-------+-------+-------+
Number of solution(s): 1
--
Solution 1
+-------+-------+-------+
| 4 9 5 | 3 8 1 | 2 6 7 |
| 6 7 1 | 2 4 5 | 9 3 8 |
| 3 8 2 | 6 9 7 | 1 5 4 |
+-------+-------+-------+
| 2 6 3 | 5 7 8 | 4 9 1 |
| 8 1 4 | 9 6 2 | 3 7 5 |
| 9 5 7 | 1 3 4 | 6 8 2 |
+-------+-------+-------+
| 7 3 8 | 4 1 6 | 5 2 9 |
| 1 2 9 | 8 5 3 | 7 4 6 |
| 5 4 6 | 7 2 9 | 8 1 3 |
+-------+-------+-------+
--
Résoudre toutes les grilles décrites dans un fichier
Le script main3.py
permet de résoudre toutes les grilles décrites dans un fichier dont on donne le nom dans la ligne de commandes.
$ ./main3.py bdd/sudokus.bdd
L'exécution de cette commande n'affiche rien. Elle se contente de produire un fichier dont le nom est celui passé en argument suivi de l'extension .sol
. Chaque ligne de ce fichier contient
- les 81 caractères de la grille d'origine (avec éventuellement quelques mentions qui la précèdent) suivis d'un
:
; - le caractère
y
si la solution est unique ou le caractèren
s'il n'y a aucune ou plus d'une solution ; - les solutions séparées par des
:
.
Voici les trois premières lignes du fichier bdd/sudokus.bdd.sol
produit par la commande précédente :
easy:490001007000045030382600050003070401800902005907030600030006529020850000500700013:y:495381267671245938382697154263578491814962375957134682738416529129853746546729813
fiendish:020500730000490050500000000019207005060000070400908120000000006080029000096005040:y:921586734637491258548372691819237465263154879475968123152743986384629517796815342
hard:050008460004000038000030107000920003020000050700086000208090000460000900015700080:y:352178469174269538896435127581924673629317854743586291238691745467853912915742386
Toutes les grilles sont résolues
Visualiser la recherche de solution avec le script main4.py
Pour utiliser ce script il est supposé que la suite logicielle graphviz est installée.
Le script main4.py
permet de produire une image représentant l'arbre de recherche des solutions parcouru par l'algorithme de résolution mis en œuvre dans le module sudoku_solver
.
Son utilisation nécessite deux arguments sur la ligne de commande :
- une chaîne de 81 caractères représentant la grille à résoudre
- un nom pour les deux fichiers qui seront produits. Ce nom sera automatiquement complété de l'extension
.dot
pour l'un de ces deux fichiers qui contiendra une description de l'arbre dans le langage de description de graphes degraphviz
. L'autre fichier qui aura un nom complété de l'extension.png
contiendra une image au format PNG de cet arbre.
Voici ce qu'on obtient en reprenant les trois exemples précédents.
Exemple 1
$ ./main4.py 906028003040500001080900040600000070008206900030000005050003060100002080200870500 images/arbre_exple1
Sudoku to solve
+-------+-------+-------+
| 9 . 6 | . 2 8 | . . 3 |
| . 4 . | 5 . . | . . 1 |
| . 8 . | 9 . . | . 4 . |
+-------+-------+-------+
| 6 . . | . . . | . 7 . |
| . . 8 | 2 . 6 | 9 . . |
| . 3 . | . . . | . . 5 |
+-------+-------+-------+
| . 5 . | . . 3 | . 6 . |
| 1 . . | . . 2 | . 8 . |
| 2 . . | 8 7 . | 5 . . |
+-------+-------+-------+
Number of solution(s): 1
--
Solution 1
+-------+-------+-------+
| 9 1 6 | 4 2 8 | 7 5 3 |
| 3 4 2 | 5 6 7 | 8 9 1 |
| 7 8 5 | 9 3 1 | 2 4 6 |
+-------+-------+-------+
| 6 2 9 | 3 4 5 | 1 7 8 |
| 5 7 8 | 2 1 6 | 9 3 4 |
| 4 3 1 | 7 8 9 | 6 2 5 |
+-------+-------+-------+
| 8 5 7 | 1 9 3 | 4 6 2 |
| 1 9 4 | 6 5 2 | 3 8 7 |
| 2 6 3 | 8 7 4 | 5 1 9 |
+-------+-------+-------+
--
Et voici l'image produite qui montre un arbre filiforme (signe que le sudoku est facile). La grille initiale est marquée en rouge en haut, et l'unique solution est marquée en vert en bas. Le premier nœud accessible depuis le nœud rouge de départ porte la mention ('7', 0, 6)
. Cela signifie que lors de la résolution, la première case remplie a été celle de coordonnée (0, 6) (première ligne, septième colonne) et qu'on y a placé le chiffre 7.
Exemple 2
$ ./main4.py 906028003040500001080900040600000070008206900030000005050003060100002080200870000 images/arbre_exple2
Sudoku to solve
+-------+-------+-------+
| 9 . 6 | . 2 8 | . . 3 |
| . 4 . | 5 . . | . . 1 |
| . 8 . | 9 . . | . 4 . |
+-------+-------+-------+
| 6 . . | . . . | . 7 . |
| . . 8 | 2 . 6 | 9 . . |
| . 3 . | . . . | . . 5 |
+-------+-------+-------+
| . 5 . | . . 3 | . 6 . |
| 1 . . | . . 2 | . 8 . |
| 2 . . | 8 7 . | . . . |
+-------+-------+-------+
Number of solution(s): 2
--
Solution 1
+-------+-------+-------+
| 9 1 6 | 4 2 8 | 7 5 3 |
| 3 4 2 | 5 6 7 | 8 9 1 |
| 7 8 5 | 9 3 1 | 2 4 6 |
+-------+-------+-------+
| 6 2 9 | 3 4 5 | 1 7 8 |
| 5 7 8 | 2 1 6 | 9 3 4 |
| 4 3 1 | 7 8 9 | 6 2 5 |
+-------+-------+-------+
| 8 5 7 | 1 9 3 | 4 6 2 |
| 1 9 4 | 6 5 2 | 3 8 7 |
| 2 6 3 | 8 7 4 | 5 1 9 |
+-------+-------+-------+
--
Solution 2
+-------+-------+-------+
| 9 1 6 | 4 2 8 | 7 5 3 |
| 3 4 2 | 5 6 7 | 8 9 1 |
| 7 8 5 | 9 3 1 | 2 4 6 |
+-------+-------+-------+
| 6 2 9 | 3 5 4 | 1 7 8 |
| 5 7 8 | 2 1 6 | 9 3 4 |
| 4 3 1 | 7 8 9 | 6 2 5 |
+-------+-------+-------+
| 8 5 7 | 1 9 3 | 4 6 2 |
| 1 9 3 | 6 4 2 | 5 8 7 |
| 2 6 4 | 8 7 5 | 3 1 9 |
+-------+-------+-------+
L'image produite montre que pendant un certain nombre d'étapes le parcours a été linéaire (aucun choix), puis une alternative s'est révélée chaque branche de cette alternative aboutissant à une solution, d'où les deux nœuds verts.
Exemple 3
$ ./main4.py 976028003040500001080900040600000070008206900030000005050003060100002080200870500 images/arbre_exple3
Sudoku to solve
+-------+-------+-------+
| 9 7 6 | . 2 8 | . . 3 |
| . 4 . | 5 . . | . . 1 |
| . 8 . | 9 . . | . 4 . |
+-------+-------+-------+
| 6 . . | . . . | . 7 . |
| . . 8 | 2 . 6 | 9 . . |
| . 3 . | . . . | . . 5 |
+-------+-------+-------+
| . 5 . | . . 3 | . 6 . |
| 1 . . | . . 2 | . 8 . |
| 2 . . | 8 7 . | 5 . . |
+-------+-------+-------+
Number of solution(s): 0
--
L'image produite montre un arbre ne comprenant qu'un seul nœud dont aucun vert. Cela provient du fait qu'une case impossible à remplir en respectant les contraintes a été découverte : la case (0, 6).
Avec la grille ci-dessous (grille de la ligne 43 du fichier bdd/sudokus.bdd
)
+-------+-------+-------+
| 2 . . | . 5 . | 8 4 . |
| . 1 . | 7 9 . | 5 . . |
| . . . | . . 4 | . . . |
+-------+-------+-------+
| . 8 1 | . . . | 2 . 9 |
| 3 . . | . . . | . . 5 |
| 7 . 6 | . . . | 3 1 . |
+-------+-------+-------+
| . . . | 9 . . | . . . |
| . . 8 | . 2 3 | . 5 . |
| . 6 3 | . 1 . | . . 7 |
+-------+-------+-------+
l'arbre de résolution révèle que cette grille n'a qu'une seule solution (un seul nœud vert), mais les nombreux branchements révèlent aussi de nombreuses impasses (fausse route) empruntées durant la recherche.