La chose importante est d'abord de représenter la grille de telle façon que chaque case puisse contenir tous les chiffres 'candidats'. On peut par exemple réserver un tableau de 81 entiers de 16 bits. Sur ces 16 bits on en utilise 9 pour indiquer les chiffres candidats: le bit 0 pour le chiffre 1 etc.... le bit 8 pour le chiffre 9. Les 7 bits restants peuvent servir de flags pour diverses optimisations. Pour l'instant je n'en voie qu'une, qui est mettre l'un de ces bits à 1 quand la case est résolue (i.e. ne contient qu'un seul candidat), car tester qu'un groupe de 9 bits contient exactement 1 bit à 1 est une opération plus complexe que tester un flag.
Commencer par remplir la grille de la façon suivante:
1. si la case est préremplie, la marquer résolue et mettre à 1 le bit du chiffre qu'elle contient,
2. si la case n'est pas préremplie mettre le flag 'résolue' à 0 et marquer tous les chiffres comme candidats.
Ensuite appliquer les méthodes suivantes. Ces méthodes sont classées selon un ordre de priorité, la priorité 0 étant la première à mettre en oeuvre. On passe à la priorité suivante quand on ne peut plus appliquer les règles d'un niveau de priorité. On revient au niveau de priorité 0 chaque fois qu'on résoud une case, ou quand on ne peut plus appliquer les règles du dernier niveau.
priorité 0: (à appliquer à toutes les cases résolues) effacer (mettre le bit à 0) le candidat correspondant à la valeur de la case résolue dans toutes les cases de la même ligne/colonne/carré que la case résolue.
priorité 1: (suggérée par Miles) rechercher dans chaque ligne/colonne/carré les chiffres que ne sont candidat que dans une seule des 9 cases, et effacer les autres candidats de cette case.
priorité 2: (suggérée par Miles) rechercher dans chaque ligne/colonne/carré les couples de chiffres qui sont candidats ensembles dans les deux mêmes cases et seulement ces deux cases, et effacer dans ces deux cases les autres candidats. Même chose pour trois chiffres candidats dans trois cases et ces trois cases seulement, etc jusqu'au nombre maximal de candidats par case (9 mais éventuellement moins si on fait un petit comptage du max après avoir appliqué les priorités 1 et 2).
priorité 3: (très imortant je crois, car sans cette règle je n'aurais clairement pas pu résoudre la grille que j'ai proposée) rechercher dans chaque carré si un chiffre n'est candidat que dans une ligne (au plus 3 cases) ou une colonne (au plus 3 cases) de ce carré. Effacer alors ce candidat dans les 6 autres cases de la ligne ou de la colonne.
Je ne sais pas si cette méthode permet de résoudre les grilles 'diaboliques', mais elle m'a permis de résoudre celle que j'ai donné en exemple.
P.S. 1 Je ne pense pas qu'il soit utile de mettre tes 770 lignes de code dans un post. A la limite il vaudrait mieux faire un petit résumé de ta méthode.
P.S. 2 Si Trap D veut bien nous expliquer comment il fait ce serait sympa.
Partager