Sudoku
L'objectif de l'exercice est d'implémenter un résolveur de Sudoku par backtracking en OCaml, en représentant la grille comme une liste plate de 81 entiers.
let grille = [ 8; 0; 9; 0; 0; 0; 0; 0; 7;
0; 0; 0; 5; 0; 9; 0; 0; 0;
0; 3; 5; 0; 7; 0; 8; 9; 0;
0; 2; 0; 7; 0; 8; 0; 1; 0;
7; 0; 0; 0; 0; 0; 0; 0; 2;
0; 6; 0; 1; 0; 5; 4; 7; 0;
0; 9; 7; 8; 5; 4; 2; 3; 0;
0; 0; 0; 9; 0; 6; 7; 0; 0;
5; 0; 0; 0; 0; 0; 0; 0; 6 ];;
-
1IndiceParcourir la liste avec List.iteri en insérant un saut de ligne quand l'indice est multiple de 9 et en affichant un point à la place des zéros.
Écrire une fonction
show : int list -> unitqui affiche une grille de Sudoku (liste de 81 entiers) sous forme de tableau 9×9, en remplaçant chaque0par un point.et en insérant un saut de ligne toutes les 9 cases. Par exempleshow telegramaffiche la grilletelegramsur 9 lignes de 9 cases. -
2IndiceFiltrer la grille en testant si l'indice divisé par 9 correspond à la ligne cible et si l'élément égale le nombre recherché.
Écrire une fonction
in_row : int -> int -> int list -> boolqui calcule si lenumberapparaît déjà dans la même ligne que la positioni(la ligne étanti / 9) de la grilleboard. Par exemplein_row 0 8 telegramrenvoietrueetin_row 1 1 telegramrenvoiefalse. -
3IndiceFiltrer la grille en testant si l'indice modulo 9 correspond à la colonne cible et si l'élément égale le nombre recherché.
Écrire une fonction
in_col : int -> int -> int list -> boolqui calcule si lenumberapparaît déjà dans la même colonne que la positioni(la colonne étanti mod 9) de la grilleboard. Par exemplein_col 0 8 telegramrenvoietrueetin_col 1 1 telegramrenvoiefalse. -
4IndiceCalculer les bornes du bloc 3×3 par division entière par 3 puis filtrer les éléments dont l'indice tombe dans ces bornes de ligne et de colonne.
Écrire une fonction
in_block : int -> int -> int list -> boolqui calcule si lenumberapparaît déjà dans le même bloc 3×3 que la positionide la grilleboard. Le bloc est déterminé par la ligne(i / 9 / 3) * 3et la colonne(i mod 9 / 3) * 3. Par exemplein_block 0 8 telegramrenvoietrueetin_block 1 1 telegramrenvoiefalse. -
5IndiceCombiner les trois fonctions précédentes par une double négation et un ET logique pour rejeter toute collision.
Écrire une fonction
is_valid_number : int -> int -> int list -> boolqui calcule si lenumberpeut être placé à la positionide la grilleboard, c'est-à-dire s'il n'apparaît ni dans la ligne, ni dans la colonne, ni dans le bloc dei. Par exempleis_valid_number 8 0 telegramrenvoiefalseetis_valid_number 1 1 telegramrenvoietrue. -
6IndiceRécursiver sur l'indice de 0 à 81, sauter les cases non nulles, essayer les chiffres 1 à 9 via is_valid_number pour les zéros, et incrémenter un compteur mutable à l'atteinte de l'indice 81.
Écrire une fonction
sudoku : int list -> unitqui résout la grille de Sudokuboardpar backtracking : pour chaque case vide (valeur0), on essaie les chiffres de 1 à 9 en vérifiantis_valid_number, et on imprime chaque solution trouvée au formatSolution #ksuivi de la grille résolue. Par exemplesudoku telegramafficheSolution #1puis la grille complète. Pour le sudokumultipleon attend 28 solutions !
Console initialisée. En attente de l'interpréteur...