1 Introduction 2 Résoudre un sudoku

Transcription

1 Introduction 2 Résoudre un sudoku
IPT
1
2015–2016
Introduction
8 | 6 | 3
4 |8 3| 1
7 | 2 | 6
----------6 |
|28
|419| 5
| 8 | 79
L’objectif de ce TP est de reprendre contact avec les fonctions de base en Python :
manipulation de listes, de chaines de caractères, et de matrices ; importation de
fichiers.
2
TP 2
Résoudre un sudoku
I Question 3 Écrire une fonction str_to_grille(chaine) qui prend en entrée
une chaine de caractère contenant 81 chiffres et renvoie la grille correspondante.
Le TP aborde la résolution de Sudoku, qui seront représentés sous forme de matrice
Par exemple, on pourrait retrouver la grille1 donnée plus haut avec
9×9. Un 0 signifie que la case est vide. Une grille de Sudoku complète doit vérifier
ces contraintes :
str_to_grille("5300700006001950000(...)000280000419005000080079")
— Chaque case contient un chiffre entre 1 et 9.
— La grille se décompose en 9 petits carrés numérotés de 0 à 8 (numérotation
naturelle) de 9 cases chacun.
— Chaque chiffre apparait une unique fois dans chaque ligne, dans chaque colonne,
et dans chaque petit carré de la grille.
I Question 4 Écrire une fonction grille_to_str(grille) qui fait l’opération
inverse.
I Question 5 Écrire une fonction est_complete(grille) qui renvoie vrai si et
seulement si la grille est complète et correcte.
I Question 1 Rappeler la différence entre
liste=[[0]*9] * 9
et
I Question 6
liste=[[0 for i in range(9)] for j in range(9)]
et pourquoi il vaut mieux utiliser la seconde.
I Question 2 Écrire une fonction print_grille(matrice) qui affiche le contenu
de la matrice. On pourra supposer que la matrice a pour taille 9×9. La fonction
respectera la convention de style ci-dessous. Notez que la fonction print peut s’appeler avec un argument print("ab",end="") pour ne pas afficher de retour à la
ligne.
Écrire une fonction valeurs_possibles(grille,i,j) qui renvoie la liste des valeurs possibles dans la case de coordonnées (i,j) de la grille. Si la case en question
contient déjà une valeur non nulle k, alors on renvoie la liste [k]. Sinon, une valeur
est possible si elle n’apparait ni sur la ligne, ni sur la colonne associée, ni dans le
petit carré. On pourra utiliser la fonction liste.remove(a) qui retire la première
occurence de a dans liste 1 .
I Question 7 On essaye l’idée suivante : tant qu’il existe une case qui n’a qu’une
>>> grille1=[[5,3,0,0,7,0,0,0,0],[6,0,0,1,9,5,0,0,0],[0,9,8,0,0,0,0,6,0],valeur possible, alors on écrit cette valeur dans la grille, et on recommence. Appli[8,0,0,0,6,0,0,0,3],[4,0,0,8,0,3,0,0,1],[7,0,0,0,2,0,0,0,6],quer cette méthode sur la grille1 ci-dessus, à la main puis programmer une fonction
[0,6,0,0,0,0,2,8,0],[0,0,0,4,1,9,0,0,5],[0,0,0,0,8,0,0,7,9]]
completer(grille) qui fait ça pour vous.
>>> print_grille(grille1)
53 | 7 |
L’employer sur grille1. Qu’en pensez-vous ?
6 |195|
98|
| 6
1. remove a une complexité linéaire, mais c’est peu pertinent ici. . .On pourra aussi essayer de
s’en passer si on préfère.
-----------
1/2
IPT
3
2015–2016
Importer un fichier
5
TP 2
Backtracking
On trouvera sur le site les fichier 01-grilleX.txt avec X valant 1 à 5 2 . Ces fichiers Nous voulons maintenant trouver la solution d’une grille quoi qu’il arrive si elle
contiennent des grilles de Sudoku avec plus ou moins de nombres révélés (45 nombres existe. Notre technique pouvait bloquer sur une grille avec des trous. Pour éviter
ça, on va utiliser la méthode du backtracking : une fois la grille remplie au maximum,
révélés au niveau 1, 25 au niveau 5).
on prend une case qui admet plusieurs valeurs possibles, et on essaye successivement
Pour ouvrir un fichier en python, il faut se placer dans le bon répertoire en utilisant toutes les valeurs.
l’instruction os.chdir().
Pratiquement, on stocke dans une liste les instances restant à résoudre, et on essaye
de les résoudre dans l’ordre. Si on ne peut pas compléter une instance, on essaye
I Question 8 Télécharger les 5 fichiers de grilles sur le site et les placer dans de compléter une case avec toutes les valeurs possibles, et on rajoute ces instances
le répertoire (U:\TP2). Rajouter dans votre script from os import chdir puis dans la liste.
chdir(’U:\\TP2’). Ouvrir le premier fichier avec fd=open("01-grilles1.txt")
On pourra rajouter un élément a dans une liste l avec l’instruction l.append(a),
et vérifier que les grilles s’affichent correctement avec :
et on pourra sortir le dernier élément de la liste avec a = l.pop().
>>> for i in fd:
...
print(i)
I Question 12 Programmer cette résolution et résoudre des problèmes de Sudoku.
Si tout va bien, Python devrait afficher des tas de lignes de 81 caractères chacune.
Si non, il est temps d’appeler votre enseignant.
I Question 13 Adapter ce qui précède pour qu’elle sorte toutes les solutions possibles quand il y en a plusieurs. Vérifier sur quelques exemples que les instances
données n’ont qu’une seule solution. Que se passe-t-il si on retire un nombre d’une
I Question 9 Quelle est la proportion de grilles que votre méthode a réussi à grille ?
résoudre parmi les grilles de niveau 1 ? Et pour les autres niveaux ? (On doit trouver
environ 80% pour les grilles de niveau 3)
I Question 14 En bonus, résoudre cette instance de Sudoku considérée comme
très difficile :
4
1
Améliorer nos techniques
7
3
I Question 10 Une autre méthode fréquemment utilisée par les joueurs et joueuses
chevronné·e·s de Sudoku consiste à chercher dans quelle(s) position(s) peut se
trouver un chiffre qui est absent d’une ligne, une colonne ou un petit carré.
Programmer cette technique (en modifiant la fonction completer).
2
2. Grilles empruntées sur le site http://www.printable-sudoku-puzzles.com/wfiles/, où on
trouvera des tas de variantes de ces casse-tête.
2/2
8
9
6
5
5
3
9
1
8
2
4
6
I Question 11 [Pour plus tard] Chercher sur internet les autres techniques classiques de résolution de sudoku et les programmer.
9
3
1
4
7
7
3