with Support ;
with SudoGrille ;
with Gada.Text_IO ;
procedure Mission2 is
package G renames SudoGrille ;
package Txt renames GAda.Text_IO ;
type Un_Resultat is record
Combien : Integer ;
Valeur : Integer ;
end record ;
type Un_Resultat_Double is record
Combien : Integer ;
Ligne : Integer ;
Colonne : Integer ;
end record ;
function Possibles_Lignes (Grille : G.Une_Grille ; Ligne : Integer ; Val : Integer) return Un_Resultat is
NPossibles : Integer := 0 ;
NoCol : Integer ;
begin
for Col in Grille'Range(2) loop
if Grille(Ligne, Col)(Val) then
NPossibles := NPossibles + 1 ;
NoCol := Col ;
end if ;
end loop ;
return (NPossibles, NoCol) ;
end Possibles_Lignes ;
procedure Tester_Possibles_Lignes is
Res : Un_Resultat ;
begin
Res := Possibles_Lignes(G.Fabrique(G.Difficile), 1, 5) ;
Txt.Put_Line("Possibles Ligne 1 Val 5 : Combien = " & Integer'Image(Res.Combien) &
" Valeur = " & Integer'Image(Res.Valeur)) ;
end Tester_Possibles_Lignes ;
function Possibles_Colonnes (Grille : G.Une_Grille ; Col : Integer ; Val : Integer) return Un_Resultat is
NPossibles : Integer := 0 ;
NoLigne : Integer ;
begin
for Ligne in Grille'Range(1) loop
if Grille(Ligne, Col)(Val) then
NPossibles := NPossibles + 1 ;
NoLigne := Ligne ;
end if ;
end loop ;
return (NPossibles, NoLigne) ;
end Possibles_Colonnes ;
function Possibles_Sous_Mat (Grille : G.Une_Grille ; Ligne, Col : Integer ; Val : Integer) return Un_Resultat_Double is
NPossibles : Integer := 0 ;
NoLigne, NoCol : Integer ;
DepLigne : Integer := 3 * ((Ligne - 1) / 3) + 1 ;
DepCol : Integer := 3 * ((Col - 1) / 3) + 1 ;
begin
for NLigne in DepLigne..DepLigne+2 loop
for NCol in DepCol..DepCol+2 loop
if Grille(NLigne, NCol)(Val) then
NPossibles := NPossibles + 1 ;
NoLigne := NLigne ;
NoCol := NCol ;
end if ;
end loop ;
end loop ;
return (NPossibles, NoLigne, NoCol) ;
end Possibles_Sous_Mat ;
procedure Examiner_Ligne(Grille : in out G.Une_Grille ; Ligne : Integer) is
Res : Un_Resultat ;
begin
for Val in 1..G.Taille loop
Res := Possibles_Lignes(Grille, Ligne, Val) ;
if Res.Combien = 1 then
Grille(Ligne, Res.Valeur) := G.Fixe(Val) ;
end if ;
end loop ;
end Examiner_Ligne ;
procedure Examiner_Col(Grille : in out G.Une_Grille ; Col : Integer) is
Res : Un_Resultat ;
begin
for Val in 1..G.Taille loop
Res := Possibles_Colonnes(Grille, Col, Val) ;
if Res.Combien = 1 then
Grille(Res.Valeur, Col) := G.Fixe(Val) ;
end if ;
end loop ;
end Examiner_Col ;
procedure Examiner_Sous_Mat(Grille : in out G.Une_Grille ; Ligne, Col : Integer) is
Res : Un_Resultat_Double ;
begin
for Val in 1..G.Taille loop
Res := Possibles_Sous_Mat(Grille, Ligne, Col, Val) ;
if Res.Combien = 1 then
Grille(Res.Ligne, Res.Colonne) := G.Fixe(Val) ;
end if ;
end loop ;
end Examiner_Sous_Mat ;
procedure Resous (LaGrille : in out SudoGrille.Une_Grille) is
Continue : Boolean := True ;
begin
while Continue loop
Support.Propage_Tout(LaGrille, Continue) ;
for Lig in LaGrille'Range(1) loop
Examiner_Ligne(LaGrille, Lig) ;
end loop ;
for Col in LaGrille'Range(2) loop
Examiner_Col(LaGrille, Col) ;
end loop ;
for Lig in 1..G.SousTaille loop
for Col in 1..G.SousTaille loop
Examiner_Sous_Mat(LaGrille, Lig * G.SousTaille, Col * G.SousTaille) ;
end loop ;
end loop ;
end loop ;
SudoGrille.Affiche(LaGrille) ;
end Resous ;
Soduk : G.Une_Grille := G.Fabrique(G.Difficile) ;
begin
G.Affiche(Soduk) ;
Resous(Soduk) ;
end Mission2 ;