A voir également:
- Programmer un sudoku en ada
- Programmer un sms - Guide
- Programmer un mail gmail - Guide
- Mettre en veille un programme - Guide
- Programmer en basic sous windows 10 - Télécharger - Édition & Programmation
- Sudoku gratuit - Télécharger - Jeux vidéo
4 réponses
Celle-ci marche mais pas totalement, voici la version qui marche à tout les coup (et qui un peu plus jolie niveau prog)
Les commentaires dans la procédure Jeu permettent l'affichage de chaque étape de remplissage.
Par contre il n'y a pas les prérequis et la procédure Affiche est un peu custom.
Les commentaires dans la procédure Jeu permettent l'affichage de chaque étape de remplissage.
Par contre il n'y a pas les prérequis et la procédure Affiche est un peu custom.
with Ada.Text_IO; use Ada.Text_IO; with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; procedure Main is -------------------------------------------------- type TCarre is array (1 .. 9, 1 .. 9) of Integer; type TPossibles is array (1 .. 9) of Boolean; type TVectPossibles is record nb : Integer; vect : TPossibles; end record; type TCube is array (1 .. 9, 1 .. 9) of TVectPossibles; type TVectCarre is array (1 .. 40) of TCarre; type TVectCoord is array (1 .. 40, 1 .. 4) of Integer; -------------------------------------------------- procedure Affiche (Sud : in TCarre) is begin Put (" ========================================="); New_Line; for I in 1 .. 9 loop for J in 1 .. 9 loop if J mod 3 = 1 then Put (" || "); if Sud (I,J) = 0 then put (" "); else Put (Sud (I, J), 1); end if; else Put (" | "); if Sud (I,J) = 0 then put (" "); else Put (Sud (I, J), 1); end if; end if; end loop; Put (" || "); if I mod 3 = 0 then New_Line; Put (" ========================================="); New_Line; else New_Line; Put (" -----------------------------------------"); New_Line; end if; end loop; end Affiche; -------------------------------------------------- procedure Recopie (Sud : in TCarre; Sud_bis : out TCarre) is begin Sud_bis := Sud; end Recopie; -------------------------------------------------- function PlusDeCasesNulles (Sud : TCarre) return Boolean is cpt : Integer := 0; begin for I in 1 .. 9 loop for J in 1 .. 9 loop if Sud (I, J) = 0 then cpt := cpt + 1; end if; end loop; end loop; return cpt = 0; end PlusDeCasesNulles; -------------------------------------------------- function ExisteDansLigne (Sud : TCarre; Lig : Integer; Valeur : Integer) return Boolean is cpt : Integer := 0; I : Integer := 1; begin for I in 1 .. 9 loop if Sud (Lig, I) = Valeur then cpt := cpt + 1; end if; end loop; return cpt /= 0; end ExisteDansLigne; -------------------------------------------------- function ExisteDansColonne (Sud : TCarre; Col : Integer; Valeur : Integer) return Boolean is cpt : Integer := 0; I : Integer := 1; begin for I in 1 .. 9 loop if Sud (I, Col) = Valeur then cpt := cpt + 1; end if; end loop; return cpt /= 0; end ExisteDansColonne; -------------------------------------------------- function ExisteDansRegion (Sud : TCarre; lig : Integer; col : Integer; Valeur : Integer) return Boolean is X : Integer := ((lig - 1) / 3) * 3 + 1; Y : Integer := ((col - 1) / 3) * 3 + 1; X_bis : Integer := X + 2; Y_bis : Integer := Y + 2; cpt : Integer := 0; begin for I in X .. X_bis loop for J in Y .. Y_bis loop if Sud (I, J) = Valeur then cpt := cpt + 1; end if; end loop; end loop; return cpt /= 0; end ExisteDansRegion; -------------------------------------------------- procedure InitLesPossibles (VectPoss : out TVectPossibles) is begin VectPoss.nb := 0; for I in 1 .. 9 loop VectPoss.vect (I) := False; end loop; end InitLesPossibles; -------------------------------------------------- procedure InitCube (Cub : out TCube) is begin for I in 1 .. 9 loop for J in 1 .. 9 loop InitLesPossibles (Cub (I, J)); end loop; end loop; end InitCube; -------------------------------------------------- procedure ValeursPossiblesJeu (Sud : in TCarre; Cub : out TCube) is begin for I in 1 .. 9 loop for J in 1 .. 9 loop if Sud (I, J) = 0 then for K in 1 .. 9 loop if not ExisteDansLigne (Sud, I, K) and not ExisteDansColonne (Sud, J, K) and not ExisteDansRegion (Sud, I, J, K) then Cub (I, J).vect (K) := True; Cub (I, J).nb := Cub (I, J).nb + 1; end if; end loop; end if; end loop; end loop; end ValeursPossiblesJeu; -------------------------------------------------- function SeulPossibleDansLigne (Cub : TCube; Lig : Integer; valeur : Integer) return Boolean is cpt : Integer := 0; begin for I in 1 .. 9 loop if Cub (Lig, I).vect (valeur) then cpt := cpt + 1; end if; end loop; return cpt = 1; end SeulPossibleDansLigne; -------------------------------------------------- function SeulPossibleDansColonne (Cub : TCube; Col : Integer; valeur : Integer) return Boolean is cpt : Integer := 0; begin for I in 1 .. 9 loop if Cub (I, Col).vect (valeur) then cpt := cpt + 1; end if; end loop; return cpt = 1; end SeulPossibleDansColonne; -------------------------------------------------- function SeulPossibleDansRegion (Cub : TCube; lig : Integer; col : Integer; valeur : Integer) return Boolean is Cpt : Integer := 0; X : Integer := ((lig - 1) / 3) * 3 + 1; Y : Integer := ((col - 1) / 3) * 3 + 1; X_bis : Integer := X + 2; Y_bis : Integer := Y + 2; begin for I in X .. X_bis loop for J in Y .. Y_bis loop if Cub (I, J).vect (valeur) then Cpt := Cpt + 1; end if; end loop; end loop; return Cpt = 1; end SeulPossibleDansRegion; -------------------------------------------------- function CandidatUnique (Cub : TCube; lig : Integer; col : Integer; valeur : Integer) return Boolean is begin if Cub (lig, col).nb = 1 or SeulPossibleDansLigne (Cub, lig, valeur) or SeulPossibleDansColonne (Cub, col, valeur) or SeulPossibleDansRegion (Cub, lig, col, valeur) then return True; else return False; end if; end CandidatUnique; -------------------------------------------------- procedure VARIATION_COORD (num : in Integer; k1, k2 : out Integer) is -- pré-requis : num est compris entre 1 et 9 -- action : cf TP begin if num mod 3 = 1 then k1 := num + 1; k2 := num + 2; elsif num mod 3 = 2 then k1 := num - 1; k2 := num + 1; else k1 := num - 1; k2 := num - 2; end if; end VARIATION_COORD; -------------------------------------------------- function PositionUnique (Sud : TCarre; Cub : TCube; Lig : Integer; Col : Integer; Valeur : Integer) return Boolean is Lig1 : Integer; Lig2 : Integer; Col1 : Integer; Col2 : Integer; begin VARIATION_COORD (Lig, Lig1, Lig2); VARIATION_COORD (Col, Col1, Col2); if (ExisteDansLigne (Sud, Lig1, Valeur) and ExisteDansLigne (Sud, Lig2, Valeur) and ExisteDansColonne (Sud, Col1, Valeur) and ExisteDansColonne (Sud, Col2, Valeur)) or (ExisteDansLigne (Sud, Lig1, Valeur) and ExisteDansLigne (Sud, Lig2, Valeur) and Sud (Lig, Col1) /= 0 and Sud (Lig, Col2) /= 0) or (ExisteDansColonne (Sud, Col1, Valeur) and ExisteDansColonne (Sud, Col2, Valeur) and Sud (Lig1, Col) /= 0 and Sud (Lig2, Col) /= 0) then return True; else return False; end if; end PositionUnique; -------------------------------------------------- procedure Jeu (Sud : in TCarre; Sud2 : out TCarre) is Cub : TCube; begin Recopie (Sud, Sud2); InitCube (Cub); ValeursPossiblesJeu (Sud2, Cub); while not PlusDeCasesNulles (Sud2) loop for I in 1 .. 9 loop for J in 1 .. 9 loop for K in 1 .. 9 loop if Cub (I, J).vect (K) and (CandidatUnique (Cub, I, J, K) or PositionUnique (Sud2, Cub, I, J, K)) then Sud2 (I, J) := K; InitCube (Cub); ValeursPossiblesJeu (Sud2, Cub); --New_Line (9); --Affiche (Sud2); end if; end loop; end loop; end loop; end loop; end Jeu; -------------------------------------------------- procedure Init (Sud : out TCarre) is begin for I in 1 .. 9 loop for J in 1 .. 9 loop Sud (I, J) := 0; end loop; end loop; end Init; -------------------------------------------------- L : Integer; C : Integer; Nbr : Integer; Sud : TCarre; Sud2 : TCarre; begin Init (Sud); Put( "Entrez les coordonées du chiffre voulu suivit du chiffre lui même et terminez par 000" ); Get (L); Get (C); Get (Nbr); while L /= 0 loop Sud (L, C) := Nbr; Get (L); Get (C); Get (Nbr); end loop; Affiche (Sud); Jeu (Sud, Sud2); New_line (3); Affiche (Sud2); end Main;
gaara_40
Messages postés
94
Date d'inscription
mardi 2 septembre 2008
Statut
Membre
Dernière intervention
10 juin 2010
3
10 juin 2010 à 10:55
10 juin 2010 à 10:55
Pour ceux qui essayerait de s'inspirer de ce code, je vous conseille plutôt de partir sur une matrice 9*9 mais dans chaque case, au lieu de mettre directement un chiffre entre 0 et 9, mettez plutôt un tableau comprenant tous les chiffres de 1 à 9 et vous les remplacez petit à petit par des zéros, et quand il ne vous restera plus que des 0 et un seul chiffre ce sera CE chiffre ;o). J'ai fait programme de résolution de grille avec ce principe et il s'en sort pas mal jusqu'au niveau moyen mais après il kiffe pas XD.
Désolé pascalou34 de pas te donner la solution à ton problème, j'ai compilé ton code rapidement et j'ai vu en effet qu'il y avait les mêmes chiffres sur la même ligne cependant j'ai pas cherché plus loin, j'avais un peu la flegme. De toute façon, je pense que tu as du trouver la solution depuis longtemps XP, ça fait quand même 2 ans que t'as posté ce message.
Désolé pascalou34 de pas te donner la solution à ton problème, j'ai compilé ton code rapidement et j'ai vu en effet qu'il y avait les mêmes chiffres sur la même ligne cependant j'ai pas cherché plus loin, j'avais un peu la flegme. De toute façon, je pense que tu as du trouver la solution depuis longtemps XP, ça fait quand même 2 ans que t'as posté ce message.
le dernier programme me semble bon à part peut être la procédure affiche qui semble bizarre. Mais en fait le programme n'est pas finit car il manque la partit 2 avec les procédures qui résous toute les difficulté du sudoku.
Pour les futur génération d'élève de l'iut informatique de montpellier j'ai le bonheur de vous annoncer que vous n'aurais plus a travailler. Non non c juste une aide alors bonne chance. A.T! génération 2011-2012.
WITH Ada.Integer_Text_IO;
USE Ada.Integer_Text_IO;
WITH Ada.Text_IO;
USE Ada.Text_IO;
PROCEDURE Sudoku IS
-- pre requis : aucun
-- action : resoud une grille de sudoku
-- strategie : decoupage en plusieurs procedures et fonctions
TYPE TCarre IS ARRAY (1 .. 9, 1 .. 9) OF Integer;
TYPE TPossible IS ARRAY (1 .. 9) OF Boolean;
TYPE TVectPossibles IS
RECORD
NB : Integer;
Vect : TPossible;
END RECORD;
TYPE TCube IS ARRAY (1 .. 9, 1 .. 9) OF TVectPossibles;
-------------------------------------------------------------------------------------------
PROCEDURE Transform_Coord (
I : IN Integer;
K1,
K2 : OUT Integer;
A : Integer) IS
-- pre requis : aucun
-- action : donne les coordonnees des 2 autres lignes ou
-- colonnes a partir d'un numero de ligne ou colonne
-- strategie : utilisation du modulo
BEGIN
IF I mod 3=1 THEN
IF A = 1 THEN
K1:= I+1;
K2:= I+2;
ELSIF A = 2 THEN
K1 := I;
K2 := I+2;
END IF;
ELSIF I mod 3=2 THEN
K1:= I-1;
K2:= I+1;
ELSIF I mod 3 = 0 THEN
IF A = 1 THEN
K1:= I-1;
K2:= I-2;
ELSIF A = 2 THEN
K1 := I-2;
K2 := I;
END IF;
END IF;
END Transform_Coord;
-------------------------------------------------------------------------------------------
PROCEDURE Affiche (
Mat : IN TCarre) IS
-- pre requis : aucun
-- action : affiche la matrice sous la forme du jeu de sudoku
-- strategie : parcours total. on affiche une par une les valeurs des cases
BEGIN
New_Line(2);
FOR I IN 1..9 LOOP
IF I=4 OR I=7 THEN
New_Line;
END IF;
FOR J IN 1..9 LOOP
IF J=4 OR J=7 THEN
Put(" ");
END IF;
IF Mat(I,J) = 0 THEN
Put (" ");
ELSE
Put(Mat(I,J),2);
END IF;
END LOOP;
New_Line;
END LOOP;
END Affiche;
-------------------------------------------------------------------------------------------
PROCEDURE Recopie (
Mat : TCarre) IS
-- pre requis : aucun
-- resultat : duplique la matrice initiale
Copie : TCarre;
BEGIN
Copie := Mat;
END Recopie;
-------------------------------------------------------------------------------------------
FUNCTION PlusDeCasesNulles (
Mat : IN Tcarre)
RETURN Boolean IS
-- pre requis : la matrice est correctement initialisee
-- resultat : retour vrai si la matrice est remplie, faux sinon (il reste des cases a zero)
-- strategie : parcours partiel. si on trouve un zero on s'arrete, sinon on continue
BEGIN
FOR I IN 1..9 LOOP
FOR J IN 1..9 LOOP
IF Mat (I,J) = 0 THEN
RETURN (False);
END IF;
END LOOP;
END LOOP;
RETURN (True);
END PlusDeCasesNulles;
-------------------------------------------------------------------------------------------
FUNCTION ExisteDansLigne (
Mat : IN Tcarre;
Ligne : IN Integer;
X : IN Integer)
RETURN Boolean IS
-- pre requis : la matrice est correctement initialisee
-- resultat : retourne vrai si x existe dans la ligne lig, faux sinon
-- strategie : parcours partiel de la ligne lig
BEGIN
FOR I IN 1..9 LOOP
IF Mat (Ligne, I) = X THEN
RETURN (True);
END IF;
END LOOP;
RETURN False;
END ExisteDansLigne;
-------------------------------------------------------------------------------------------
FUNCTION ExisteDansColonne (
Mat : IN Tcarre;
Colonne : IN Integer;
X : IN Integer)
RETURN Boolean IS
-- pre requis : la matrice est correctement initialisee
-- resultat : retourne vrai si x existe dans la colonne col, faux sinon
-- strategie : parcours partiel de la colonne col
BEGIN
FOR I IN 1..9 LOOP
IF Mat (I, Colonne) = X THEN
RETURN (True);
END IF;
END LOOP;
RETURN (False);
END ExisteDansColonne;
-------------------------------------------------------------------------------------------
FUNCTION ExisteDansRegion (
Mat : IN Tcarre;
I,
J : IN Integer;
X : IN Integer)
RETURN Boolean IS
-- pre requis : la matrice est correctement initialisee
-- resultat : retourne vrai si x existe dans la region indicees par (lig,col), faux sinon
-- strategie : parcours partiel de la region
L1,
L2 : Integer; -- lignes
C1,
C2 : Integer; -- colonnes
BEGIN
Transform_Coord (I, L1, L2, 2);
Transform_Coord (J, C1, C2, 2);
FOR I IN L1..L2 LOOP
FOR J IN C1..C2 LOOP
IF Mat (I, J) = X THEN
RETURN (True);
END IF;
END LOOP;
END LOOP;
RETURN (False);
END ExisteDansRegion;
-------------------------------------------------------------------------------------------
PROCEDURE InitLesPossibles (
Possibles : OUT TVectPossibles) IS
-- pre requis : aucun
-- action : initialise les deux champ de TVectPossible
-- strategie : parcours total
BEGIN
FOR I IN 1..9 LOOP
Possibles.Vect (I) := False;
END LOOP;
Possibles.Nb :=0;
END InitLesPossibles;
-------------------------------------------------------------------------------------------
PROCEDURE InitCube (
Cube : OUT TCube) IS
-- pre requis : aucun
-- action : initialise tout le cube a faux
-- strategie : parcours total
BEGIN
FOR I IN 1..9 LOOP
FOR J IN 1..9 LOOP
Cube(I,J).Nb := 0;
FOR K IN 1..9 LOOP
Cube(I,J).Vect(K) := False;
END LOOP;
END LOOP;
END LOOP;
END InitCube;
-------------------------------------------------------------------------------------------
PROCEDURE ValeursPossiblesJeu (
Mat : IN Tcarre;
Cube : IN OUT Tcube) IS
-- pre requis : la matrice et le cube sont correctement initialises
-- action : calcule les valeurs possibles de chaque nombre
-- strategie : parcours total de la matrice
BEGIN
FOR I IN 1..9 LOOP
FOR J IN 1..9 LOOP
IF Mat(I,J)=0 THEN
FOR K IN 1..9 LOOP
IF NOT Existedansligne (Mat,I,K) AND NOT Existedanscolonne (Mat,J,K) AND NOT Existedansregion (Mat,I,J,K) THEN
Cube(I,J).Vect(K):=True;
Cube(I,J).Nb:=Cube(I,J).Nb+1;
END IF;
END LOOP;
END IF;
END LOOP;
END LOOP;
END ValeursPossiblesJeu;
-------------------------------------------------------------------------------------------
FUNCTION SeulPossibleDansLigne (
Cube : TCube;
Lig : Integer;
X : Integer)
RETURN Boolean IS
-- pre requis : la matrice est correctement initialisee
-- resultat : retourne vrai si x est le seul possible dans la ligne, faux sinon
-- strategie : parcours partiel de la ligne lig
Cpt : Integer := 0;
BEGIN
FOR I IN 1..9 LOOP
IF Cube ( Lig, I ).Vect(X) THEN
Cpt := Cpt + 1;
END IF;
END LOOP;
RETURN (Cpt=1);
END SeulPossibleDansLigne;
-------------------------------------------------------------------------------------------
FUNCTION SeulPossibleDansColonne (
Cube : TCube;
Col : Integer;
X : Integer)
RETURN Boolean IS
-- pre requis : la matrice est correctement initialisee
-- resultat : retourne vrai si x est le seul possible dans la colonne, faux sinon
-- strategie : parcours integrel de la colonne col
Cpt : Integer := 0;
BEGIN
FOR I IN 1..9 LOOP
IF Cube ( Col, I ).Vect(X) THEN
Cpt := Cpt + 1;
END IF;
END LOOP;
RETURN (Cpt=1);
END SeulPossibleDansColonne;
-------------------------------------------------------------------------------------------
FUNCTION SeulPossibleDansRegion (
Cube : TCube;
Lig : Integer;
Col : Integer;
X : Integer)
RETURN Boolean IS
-- pre requis : la matrice est correctement initialisee
-- resultat : retourne vrai si x est le seul possible dans la region, faux sinon
-- strategie : parcours integrel
Cpt : Integer := 0;
L1,
L2 : Integer; -- lignes
C1,
C2 : Integer; -- colonnes
BEGIN
Transform_Coord (Lig, L1, L2, 2);
Transform_Coord (Col, C1, C2, 2);
FOR I IN L1..L2 LOOP
FOR J IN C1..C2 LOOP
IF Cube ( I, J ).Vect(X) THEN
Cpt := Cpt + 1;
END IF;
END LOOP;
END LOOP;
RETURN (Cpt=1);
END SeulPossibleDansRegion;
-------------------------------------------------------------------------------------------
FUNCTION CandidatUnique (
Cube : IN Tcube;
Mat : IN TCarre;
Lig,
Col,
X : IN Integer)
RETURN Boolean IS
-- pre requis : la matrice et le cube sont correctement initialises
-- resultat : retourne vrai si x est le seul possible pour une case donnee, faux sinon
-- strategie : si le chiffre est le seul possible dans la ligne ou la colonne ou la region,
-- alors la valeur est verifiee
BEGIN
IF (SeulPossibleDansLigne (Cube, Lig, X ) OR SeulPossibleDansColonne (Cube, Col, X) OR SeulPossibleDansRegion ( Cube, Lig, Col, X ))THEN
RETURN ( True );
ELSE
RETURN ( False );
END IF;
END CandidatUnique;
-------------------------------------------------------------------------------------------
FUNCTION PositionUnique (
Mat : IN TCarre;
I,
J,
X : IN Integer)
RETURN Boolean IS
-- pre requis : la matrice est correctement initialisee
-- resultat : retourne vrai si la position du chiffre est unique, faux sinon
-- strategie : on regardes si les autres cases sont occupees
Cpt,
Cpt1 : Integer := 0;
L1,
L2 : Integer; -- lignes
C1,
C2 : Integer; -- colonnes
BEGIN
Transform_Coord (I,L1,L2,1);
Transform_Coord (J,C1,C2,1);
FOR Z IN L1..L2 LOOP
IF Mat ( I, Z ) = 0 THEN
Cpt := Cpt + 1;
END IF;
END LOOP;
FOR E IN C1..C2 LOOP
IF Mat ( E, J ) = 0 THEN
Cpt1 := Cpt1 + 1;
END IF;
END LOOP;
IF ((ExisteDansLigne (Mat, L1, X) AND ExisteDansLigne (Mat, L2, X) AND ExisteDansColonne (Mat, C1, X) AND ExisteDansColonne (Mat, C2, X) )
OR (ExisteDansLigne (Mat, L1, X) AND ExisteDansLigne (Mat, L2, X) AND Cpt1 = 1)
OR (ExisteDansColonne (Mat, C1, X) AND ExisteDansColonne (Mat, C2, X) AND Cpt = 1)) THEN
RETURN ( True );
ELSE
RETURN ( False );
END IF;
END PositionUnique;
-------------------------------------------------------------------------------------------
PROCEDURE Jeu (
Mat : IN OUT TCarre;
Cube : IN OUT TCube;
Possibles : IN OUT TVectPossibles) IS
BEGIN
InitCube ( Cube );
InitLesPossibles ( Possibles );
ValeursPossiblesJeu ( Mat, Cube );
WHILE NOT PlusDeCasesNulles (Mat) LOOP
FOR I IN 1..9 LOOP
FOR J IN 1..9 LOOP
IF Mat(I,J)=0 THEN
FOR K IN 1..9 LOOP
IF (PositionUnique (Mat,I,J,K)
OR CandidatUnique (Cube,Mat,I,J,K))
AND NOT Existedansligne (Mat, I, K)
AND NOT Existedanscolonne (Mat, J, K)
AND NOT Existedansregion (Mat, I, J, K)THEN
IF Cube (I,J).Vect (K) THEN
Mat(I,J):=K;
FOR Z IN 1..9 LOOP
Cube(I,J).Vect(Z):=False;
END LOOP;
Cube(I,J).Nb:=Cube(I,J).Nb-1;
ValeursPossiblesJeu ( Mat, Cube );
END IF;
END IF;
END LOOP;
END IF;
END LOOP;
END LOOP;
END LOOP;
END Jeu;
Possibles : TVectPossibles;
Cube : Tcube;
Mat : Tcarre := (
(1, 3, 7, 0, 2, 8, 0, 6, 5),
(0, 0, 5, 0, 7, 0, 4, 3, 0),
(0, 0, 6, 1, 3, 0, 2, 0, 0),
(5, 8, 0, 7, 0, 0, 3, 0, 2),
(0, 0, 4, 3, 0, 2, 1, 0, 0),
(2, 0, 3, 0, 0, 1, 0, 8, 6),
(0, 0, 8, 0, 1, 4, 6, 0, 0),
(0, 1, 2, 0, 6, 0, 5, 0, 0),
(4, 6, 0, 2, 5, 0, 8, 1, 7)
);
BEGIN
Affiche (Mat);
New_Line;
Jeu (Mat,Cube, Possibles);
Put("--------------------");
New_Line;
Affiche (Mat);
END Sudoku;
WITH Ada.Integer_Text_IO;
USE Ada.Integer_Text_IO;
WITH Ada.Text_IO;
USE Ada.Text_IO;
PROCEDURE Sudoku IS
-- pre requis : aucun
-- action : resoud une grille de sudoku
-- strategie : decoupage en plusieurs procedures et fonctions
TYPE TCarre IS ARRAY (1 .. 9, 1 .. 9) OF Integer;
TYPE TPossible IS ARRAY (1 .. 9) OF Boolean;
TYPE TVectPossibles IS
RECORD
NB : Integer;
Vect : TPossible;
END RECORD;
TYPE TCube IS ARRAY (1 .. 9, 1 .. 9) OF TVectPossibles;
-------------------------------------------------------------------------------------------
PROCEDURE Transform_Coord (
I : IN Integer;
K1,
K2 : OUT Integer;
A : Integer) IS
-- pre requis : aucun
-- action : donne les coordonnees des 2 autres lignes ou
-- colonnes a partir d'un numero de ligne ou colonne
-- strategie : utilisation du modulo
BEGIN
IF I mod 3=1 THEN
IF A = 1 THEN
K1:= I+1;
K2:= I+2;
ELSIF A = 2 THEN
K1 := I;
K2 := I+2;
END IF;
ELSIF I mod 3=2 THEN
K1:= I-1;
K2:= I+1;
ELSIF I mod 3 = 0 THEN
IF A = 1 THEN
K1:= I-1;
K2:= I-2;
ELSIF A = 2 THEN
K1 := I-2;
K2 := I;
END IF;
END IF;
END Transform_Coord;
-------------------------------------------------------------------------------------------
PROCEDURE Affiche (
Mat : IN TCarre) IS
-- pre requis : aucun
-- action : affiche la matrice sous la forme du jeu de sudoku
-- strategie : parcours total. on affiche une par une les valeurs des cases
BEGIN
New_Line(2);
FOR I IN 1..9 LOOP
IF I=4 OR I=7 THEN
New_Line;
END IF;
FOR J IN 1..9 LOOP
IF J=4 OR J=7 THEN
Put(" ");
END IF;
IF Mat(I,J) = 0 THEN
Put (" ");
ELSE
Put(Mat(I,J),2);
END IF;
END LOOP;
New_Line;
END LOOP;
END Affiche;
-------------------------------------------------------------------------------------------
PROCEDURE Recopie (
Mat : TCarre) IS
-- pre requis : aucun
-- resultat : duplique la matrice initiale
Copie : TCarre;
BEGIN
Copie := Mat;
END Recopie;
-------------------------------------------------------------------------------------------
FUNCTION PlusDeCasesNulles (
Mat : IN Tcarre)
RETURN Boolean IS
-- pre requis : la matrice est correctement initialisee
-- resultat : retour vrai si la matrice est remplie, faux sinon (il reste des cases a zero)
-- strategie : parcours partiel. si on trouve un zero on s'arrete, sinon on continue
BEGIN
FOR I IN 1..9 LOOP
FOR J IN 1..9 LOOP
IF Mat (I,J) = 0 THEN
RETURN (False);
END IF;
END LOOP;
END LOOP;
RETURN (True);
END PlusDeCasesNulles;
-------------------------------------------------------------------------------------------
FUNCTION ExisteDansLigne (
Mat : IN Tcarre;
Ligne : IN Integer;
X : IN Integer)
RETURN Boolean IS
-- pre requis : la matrice est correctement initialisee
-- resultat : retourne vrai si x existe dans la ligne lig, faux sinon
-- strategie : parcours partiel de la ligne lig
BEGIN
FOR I IN 1..9 LOOP
IF Mat (Ligne, I) = X THEN
RETURN (True);
END IF;
END LOOP;
RETURN False;
END ExisteDansLigne;
-------------------------------------------------------------------------------------------
FUNCTION ExisteDansColonne (
Mat : IN Tcarre;
Colonne : IN Integer;
X : IN Integer)
RETURN Boolean IS
-- pre requis : la matrice est correctement initialisee
-- resultat : retourne vrai si x existe dans la colonne col, faux sinon
-- strategie : parcours partiel de la colonne col
BEGIN
FOR I IN 1..9 LOOP
IF Mat (I, Colonne) = X THEN
RETURN (True);
END IF;
END LOOP;
RETURN (False);
END ExisteDansColonne;
-------------------------------------------------------------------------------------------
FUNCTION ExisteDansRegion (
Mat : IN Tcarre;
I,
J : IN Integer;
X : IN Integer)
RETURN Boolean IS
-- pre requis : la matrice est correctement initialisee
-- resultat : retourne vrai si x existe dans la region indicees par (lig,col), faux sinon
-- strategie : parcours partiel de la region
L1,
L2 : Integer; -- lignes
C1,
C2 : Integer; -- colonnes
BEGIN
Transform_Coord (I, L1, L2, 2);
Transform_Coord (J, C1, C2, 2);
FOR I IN L1..L2 LOOP
FOR J IN C1..C2 LOOP
IF Mat (I, J) = X THEN
RETURN (True);
END IF;
END LOOP;
END LOOP;
RETURN (False);
END ExisteDansRegion;
-------------------------------------------------------------------------------------------
PROCEDURE InitLesPossibles (
Possibles : OUT TVectPossibles) IS
-- pre requis : aucun
-- action : initialise les deux champ de TVectPossible
-- strategie : parcours total
BEGIN
FOR I IN 1..9 LOOP
Possibles.Vect (I) := False;
END LOOP;
Possibles.Nb :=0;
END InitLesPossibles;
-------------------------------------------------------------------------------------------
PROCEDURE InitCube (
Cube : OUT TCube) IS
-- pre requis : aucun
-- action : initialise tout le cube a faux
-- strategie : parcours total
BEGIN
FOR I IN 1..9 LOOP
FOR J IN 1..9 LOOP
Cube(I,J).Nb := 0;
FOR K IN 1..9 LOOP
Cube(I,J).Vect(K) := False;
END LOOP;
END LOOP;
END LOOP;
END InitCube;
-------------------------------------------------------------------------------------------
PROCEDURE ValeursPossiblesJeu (
Mat : IN Tcarre;
Cube : IN OUT Tcube) IS
-- pre requis : la matrice et le cube sont correctement initialises
-- action : calcule les valeurs possibles de chaque nombre
-- strategie : parcours total de la matrice
BEGIN
FOR I IN 1..9 LOOP
FOR J IN 1..9 LOOP
IF Mat(I,J)=0 THEN
FOR K IN 1..9 LOOP
IF NOT Existedansligne (Mat,I,K) AND NOT Existedanscolonne (Mat,J,K) AND NOT Existedansregion (Mat,I,J,K) THEN
Cube(I,J).Vect(K):=True;
Cube(I,J).Nb:=Cube(I,J).Nb+1;
END IF;
END LOOP;
END IF;
END LOOP;
END LOOP;
END ValeursPossiblesJeu;
-------------------------------------------------------------------------------------------
FUNCTION SeulPossibleDansLigne (
Cube : TCube;
Lig : Integer;
X : Integer)
RETURN Boolean IS
-- pre requis : la matrice est correctement initialisee
-- resultat : retourne vrai si x est le seul possible dans la ligne, faux sinon
-- strategie : parcours partiel de la ligne lig
Cpt : Integer := 0;
BEGIN
FOR I IN 1..9 LOOP
IF Cube ( Lig, I ).Vect(X) THEN
Cpt := Cpt + 1;
END IF;
END LOOP;
RETURN (Cpt=1);
END SeulPossibleDansLigne;
-------------------------------------------------------------------------------------------
FUNCTION SeulPossibleDansColonne (
Cube : TCube;
Col : Integer;
X : Integer)
RETURN Boolean IS
-- pre requis : la matrice est correctement initialisee
-- resultat : retourne vrai si x est le seul possible dans la colonne, faux sinon
-- strategie : parcours integrel de la colonne col
Cpt : Integer := 0;
BEGIN
FOR I IN 1..9 LOOP
IF Cube ( Col, I ).Vect(X) THEN
Cpt := Cpt + 1;
END IF;
END LOOP;
RETURN (Cpt=1);
END SeulPossibleDansColonne;
-------------------------------------------------------------------------------------------
FUNCTION SeulPossibleDansRegion (
Cube : TCube;
Lig : Integer;
Col : Integer;
X : Integer)
RETURN Boolean IS
-- pre requis : la matrice est correctement initialisee
-- resultat : retourne vrai si x est le seul possible dans la region, faux sinon
-- strategie : parcours integrel
Cpt : Integer := 0;
L1,
L2 : Integer; -- lignes
C1,
C2 : Integer; -- colonnes
BEGIN
Transform_Coord (Lig, L1, L2, 2);
Transform_Coord (Col, C1, C2, 2);
FOR I IN L1..L2 LOOP
FOR J IN C1..C2 LOOP
IF Cube ( I, J ).Vect(X) THEN
Cpt := Cpt + 1;
END IF;
END LOOP;
END LOOP;
RETURN (Cpt=1);
END SeulPossibleDansRegion;
-------------------------------------------------------------------------------------------
FUNCTION CandidatUnique (
Cube : IN Tcube;
Mat : IN TCarre;
Lig,
Col,
X : IN Integer)
RETURN Boolean IS
-- pre requis : la matrice et le cube sont correctement initialises
-- resultat : retourne vrai si x est le seul possible pour une case donnee, faux sinon
-- strategie : si le chiffre est le seul possible dans la ligne ou la colonne ou la region,
-- alors la valeur est verifiee
BEGIN
IF (SeulPossibleDansLigne (Cube, Lig, X ) OR SeulPossibleDansColonne (Cube, Col, X) OR SeulPossibleDansRegion ( Cube, Lig, Col, X ))THEN
RETURN ( True );
ELSE
RETURN ( False );
END IF;
END CandidatUnique;
-------------------------------------------------------------------------------------------
FUNCTION PositionUnique (
Mat : IN TCarre;
I,
J,
X : IN Integer)
RETURN Boolean IS
-- pre requis : la matrice est correctement initialisee
-- resultat : retourne vrai si la position du chiffre est unique, faux sinon
-- strategie : on regardes si les autres cases sont occupees
Cpt,
Cpt1 : Integer := 0;
L1,
L2 : Integer; -- lignes
C1,
C2 : Integer; -- colonnes
BEGIN
Transform_Coord (I,L1,L2,1);
Transform_Coord (J,C1,C2,1);
FOR Z IN L1..L2 LOOP
IF Mat ( I, Z ) = 0 THEN
Cpt := Cpt + 1;
END IF;
END LOOP;
FOR E IN C1..C2 LOOP
IF Mat ( E, J ) = 0 THEN
Cpt1 := Cpt1 + 1;
END IF;
END LOOP;
IF ((ExisteDansLigne (Mat, L1, X) AND ExisteDansLigne (Mat, L2, X) AND ExisteDansColonne (Mat, C1, X) AND ExisteDansColonne (Mat, C2, X) )
OR (ExisteDansLigne (Mat, L1, X) AND ExisteDansLigne (Mat, L2, X) AND Cpt1 = 1)
OR (ExisteDansColonne (Mat, C1, X) AND ExisteDansColonne (Mat, C2, X) AND Cpt = 1)) THEN
RETURN ( True );
ELSE
RETURN ( False );
END IF;
END PositionUnique;
-------------------------------------------------------------------------------------------
PROCEDURE Jeu (
Mat : IN OUT TCarre;
Cube : IN OUT TCube;
Possibles : IN OUT TVectPossibles) IS
BEGIN
InitCube ( Cube );
InitLesPossibles ( Possibles );
ValeursPossiblesJeu ( Mat, Cube );
WHILE NOT PlusDeCasesNulles (Mat) LOOP
FOR I IN 1..9 LOOP
FOR J IN 1..9 LOOP
IF Mat(I,J)=0 THEN
FOR K IN 1..9 LOOP
IF (PositionUnique (Mat,I,J,K)
OR CandidatUnique (Cube,Mat,I,J,K))
AND NOT Existedansligne (Mat, I, K)
AND NOT Existedanscolonne (Mat, J, K)
AND NOT Existedansregion (Mat, I, J, K)THEN
IF Cube (I,J).Vect (K) THEN
Mat(I,J):=K;
FOR Z IN 1..9 LOOP
Cube(I,J).Vect(Z):=False;
END LOOP;
Cube(I,J).Nb:=Cube(I,J).Nb-1;
ValeursPossiblesJeu ( Mat, Cube );
END IF;
END IF;
END LOOP;
END IF;
END LOOP;
END LOOP;
END LOOP;
END Jeu;
Possibles : TVectPossibles;
Cube : Tcube;
Mat : Tcarre := (
(1, 3, 7, 0, 2, 8, 0, 6, 5),
(0, 0, 5, 0, 7, 0, 4, 3, 0),
(0, 0, 6, 1, 3, 0, 2, 0, 0),
(5, 8, 0, 7, 0, 0, 3, 0, 2),
(0, 0, 4, 3, 0, 2, 1, 0, 0),
(2, 0, 3, 0, 0, 1, 0, 8, 6),
(0, 0, 8, 0, 1, 4, 6, 0, 0),
(0, 1, 2, 0, 6, 0, 5, 0, 0),
(4, 6, 0, 2, 5, 0, 8, 1, 7)
);
BEGIN
Affiche (Mat);
New_Line;
Jeu (Mat,Cube, Possibles);
Put("--------------------");
New_Line;
Affiche (Mat);
END Sudoku;