• Aucun résultat trouvé

nombre de carrés 3x3 compatibles NbSol: Integer

N/A
N/A
Protected

Academic year: 2022

Partager "nombre de carrés 3x3 compatibles NbSol: Integer"

Copied!
3
0
0

Texte intégral

(1)

unit U_sudoku;

interface uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;

type T9b = array[1..9] of Byte;

TSA = record AR: T9b;

cp: Integer;

end;

TForm1 = class(TForm) Memo1: TMemo;

SearchBtn: TButton;

procedure SearchBtnClick(Sender: TObject);

public

{ Déclarations publiques }

NbC3x3, // nombre de carrés 3x3 compatibles NbSol: Integer; // nombre de solutions du sudoku Contr: array[1..9] of Integer; // Contraintes

CComp: array[1..10000] of TSA; // Carrés 3x3 compatibles procedure Contraintes;

procedure Generation;

function Test(AX,AY,AZ: T9b; p,q,r: Integer): Boolean;

end;

var Form1: TForm1;

implementation {$R *.DFM}

procedure TForm1.Contraintes;

// transformation des contraintes de l'énoncé en valeur numérique // conservée dans Contr[1..9]

var

j,k,p,q: Integer;

stx: String;

const

v: array[1..9] of String

= ('101001011000','100001101001','011110000100', '100011110101','100110100110','001001011010', '110101100010','010110010100','100101110111');

// contraintes de l'énoncé dans chacun des carrés 3x3:

// 1=> 0=< dans l'ordre de gauche à droite pour les

// lignes 1 à 3, puis de haut en bas pour les colonnes 1 à 3 begin

// conversion chaîne v (écriture binaire) -> nombre for j := 1 to 9 do

begin

stx := v[j]; p := 0; q := 1;

for k := 1 to 12 do begin

if stx[k]='1' then Inc(p,q);

q := q*2;

end;

Contr[j] := p;

end;

end;

procedure TForm1.Generation;

// génération de tous les carrés 3x3 compatibles et classement en // 9 listes (compatible avec la position 'a','b',.. dans le sudoku) // un carré = | a b c |

// | d e f | // | g h i | var

a,b,c,d,e,f,g,h,i,j,s: Integer;

tx: array[1..9] of Integer;

AX: T9b;

stx: String;

begin

NbC3x3 := 0;

for a := 1 to 9 do

for b := 1 to 9 do if (b<>a) then

for c := 1 to 9 do if (c<>a) and (c<>b) then

(2)

for d := 1 to 9 do if (d<>a) and (d<>b) and (d<>c) then

for e := 1 to 9 do if (e<>a) and (e<>b) and (e<>c) and (e<>d) then

for f := 1 to 9 do if (f<>a) and (f<>b) and (f<>c) and (f<>d) and (f<>e) then

for g := 1 to 9 do if (g<>a) and (g<>b) and (g<>c) and (g<>d) and (g<>e) and (g<>f) then for h := 1 to 9 do if (h<>a) and (h<>b) and (h<>c) and (h<>d) and (h<>e) and (h<>f) and (h<>g) then

for i := 1 to 9 do if (i<>a) and (i<>b) and (i<>c) and (i<>d) and (i<>e) and (i<>f) and (i<>g) and (i<>h) then

begin s := 0;

if a>b then Inc(s);

if b>c then Inc(s,2);

if d>e then Inc(s,4);

if e>f then Inc(s,8);

if g>h then Inc(s,16);

if h>i then Inc(s,32);

if a>d then Inc(s,64);

if d>g then Inc(s,128);

if b>e then Inc(s,256);

if e>h then Inc(s,512);

if c>f then Inc(s,1024);

if f>i then Inc(s,2048);

for j := 1 to 9 do if s = Contr[j] then begin

Inc(NbC3x3);

AX[1] := a; AX[2] := b; AX[3] := c; AX[4] := d; AX[5] := e;

AX[6] := f; AX[7] := g; AX[8] := h; AX[9] := i;

// on garde dans CComp[1..x] la composition du carré et sa position possible with CComp[NbC3x3] do

begin

AR := AX; cp := j;

end;

end;

end;

// pour connaitre le nombre total NbC3x3 et la répartition tx[1..9]

// des carrés 3x3 compatibles

Memo1.Lines.Add(Format('carrés 3x3 compatibles NbC3x3=%d',[NbC3x3]));

FillChar(tx, SizeOf(tx), 0);

for j := 1 to NbC3x3 do Inc(tx[CComp[j].cp]);

stx := '';

for j := 1 to 9 do stx := stx + Format('%d:%d ',[j,tx[j]]);

Memo1.Lines.Add(stx);

end;

function TForm1.Test(AX,AY,AZ: T9b; p,q,r: Integer): Boolean;

// Test de compatibilité de ligne ou de colonne de 9 chiffres // AX1, AX4, AX7 sont les carrés 3x3 d'où sont extraits les // chiffres en position p, q, r

// un carré = | 1 2 3 | // | 4 5 6 | // | 7 8 9 | var

j: Integer;

bx: array[1..9] of Boolean;

begin

FillChar(bx, SizeOf(bx), 0); // False partout bx[AX[p]] := True;

bx[AX[q]] := True;

bx[AX[r]] := True;

bx[AY[p]] := True;

bx[AY[q]] := True;

bx[AY[r]] := True;

bx[AZ[p]] := True;

bx[AZ[q]] := True;

bx[AZ[r]] := True;

Result := True;

for j := 1 to 9 do if not bx[j] then Result := False;

end;

procedure TForm1.SearchBtnClick(Sender: TObject);

var

j1,j2,j3,j4,j5,j6,j7,j8,j9: Integer;

AX1,AX2,AX3,AX4,AX5,AX6,AX7,AX8,AX9: T9b;

begin

Contraintes;

Generation;

// Et voici la recherche proprement dite

// L'ordre des tests est orienté par les résultats de Génération // de façon à commencer par les carrés compatibles les mooins nombreux

(3)

// et introduire en dernier ceux du centre (AX5) NbSol := 0;

for j1 := 1 to NbC3x3 do if CComp[j1].cp=1 then for j4 := 1 to NbC3x3 do if CComp[j4].cp=4 then for j7 := 1 to NbC3x3 do if CComp[j7].cp=7 then begin

AX1 := CComp[j1].AR;

AX4 := CComp[j4].AR;

AX7 := CComp[j7].AR;

if Test(AX1,AX4,AX7,1,4,7) and Test(AX1,AX4,AX7,2,5,8) and Test(AX1,AX4,AX7,3,6,9) then begin

for j2 := 1 to NbC3x3 do if CComp[j2].cp=2 then for j3 := 1 to NbC3x3 do if CComp[j3].cp=3 then begin

AX2 := CComp[j2].AR;

AX3 := CComp[j3].AR;

if Test(AX1,AX2,AX3,1,2,3) and Test(AX1,AX2,AX3,4,5,6) and Test(AX1,AX2,AX3,7,8,9) then begin

for j5 := 1 to NbC3x3 do if CComp[j5].cp=5 then for j6 := 1 to NbC3x3 do if CComp[j6].cp=6 then begin

AX5 := CComp[j5].AR;

AX6 := CComp[j6].AR;

if Test(AX4,AX5,AX6,1,2,3) and Test(AX4,AX5,AX6,4,5,6) and Test(AX4,AX5,AX6,7,8,9) then begin

for j8 := 1 to NbC3x3 do if CComp[j8].cp=8 then for j9 := 1 to NbC3x3 do if CComp[j9].cp=9 then begin

AX8 := CComp[j8].AR;

AX9 := CComp[j9].AR;

if Test(AX7,AX8,AX9,1,2,3) and Test(AX7,AX8,AX9,4,5,6) and Test(AX7,AX8,AX9,7,8,9) and Test(AX3,AX6,AX9,1,4,7) and Test(AX3,AX6,AX9,2,5,8) and Test(AX3,AX6,AX9,3,6,9) and Test(AX2,AX5,AX8,1,4,7) and Test(AX2,AX5,AX8,2,5,8) and Test(AX2,AX5,AX8,3,6,9) then begin

Inc(NbSol);

Memo1.Lines.Add(Format('Essai %d',[NbSol]));

Memo1.Lines.Add(Format('%d %d %d %d %d %d %d %d %d ', [AX1[1],AX1[2],AX1[3],AX2[1],AX2[2],AX2[3],AX3[1],AX3[2],AX3[3]]));

Memo1.Lines.Add(Format('%d %d %d %d %d %d %d %d %d ', [AX1[4],AX1[5],AX1[6],AX2[4],AX2[5],AX2[6],AX3[4],AX3[5],AX3[6]]));

Memo1.Lines.Add(Format('%d %d %d %d %d %d %d %d %d ', [AX1[7],AX1[8],AX1[9],AX2[7],AX2[8],AX2[9],AX3[7],AX3[8],AX3[9]]));

Memo1.Lines.Add(Format('%d %d %d %d %d %d %d %d %d ', [AX4[1],AX4[2],AX4[3],AX5[1],AX5[2],AX5[3],AX6[1],AX6[2],AX6[3]]));

Memo1.Lines.Add(Format('%d %d %d %d %d %d %d %d %d ', [AX4[4],AX4[5],AX4[6],AX5[4],AX5[5],AX5[6],AX6[4],AX6[5],AX6[6]]));

Memo1.Lines.Add(Format('%d %d %d %d %d %d %d %d %d ', [AX4[7],AX4[8],AX4[9],AX5[7],AX5[8],AX5[9],AX6[7],AX6[8],AX6[9]]));

Memo1.Lines.Add(Format('%d %d %d %d %d %d %d %d %d ', [AX7[1],AX7[2],AX7[3],AX8[1],AX8[2],AX8[3],AX9[1],AX9[2],AX9[3]]));

Memo1.Lines.Add(Format('%d %d %d %d %d %d %d %d %d ', [AX7[4],AX7[5],AX7[6],AX8[4],AX8[5],AX8[6],AX9[4],AX9[5],AX9[6]]));

Memo1.Lines.Add(Format('%d %d %d %d %d %d %d %d %d ', [AX7[7],AX7[8],AX7[9],AX8[7],AX8[8],AX8[9],AX9[7],AX9[8],AX9[9]]));

end;

end;

end;

end;

end;

end;

end;

end;

Memo1.Lines.Add('');

Memo1.Lines.Add('Fini');

end;

end.

Références

Documents relatifs

Sur la fiche de résultats (fournie par le comité départemental de la Corrèze), sont identifiés les joueurs ayant participé, le correspondant Event Maker du

Nous lançons une nouvelle offre d’achats groupés de structures gonflables pour nos Ligues, Comités et Clubs (date limite pour commander : 31 mars 2021) :. - Terrain 3x3 10x10m -

Un système triangulé équivalent

Pour l’équipe vainqueur, le résultat de cette rencontre ne doit pas être pris en compte dans le calcul du score moyen de cette équipe tandis que pour l’équipe perdante

Une grille de Sudoku, puzzle très en vogue en Japon, est faite de la juxtaposition de 9 carrés 3x3. Chacun de ces carrés comporte tous les chiffres de 1 à 9 une fois et

[r]

Théorème – Pour tout naturel k , il existe un cercle du plan qui contient en son intérieur exactement k points intègres.. Une démonstration particulièrement élégante de

Gauss, qui exprime de combien de manières un nombre entier peut être dé- composé en deux carrés (voir Nouvelles Annales, t... et