Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
Delphi 10.4 Sydney
|
AW: Sudoku Array of Array vergleichen
19. Nov 2011, 20:52
Hab’s mal ausprobiert, allerdings etwas anders. Die Quadranten nenne ich hier Blöcke. Als Grundlage der Suche benutze ich eine Pemutliste. Geht recht flott so, < 2 sec..
Delphi-Quellcode:
function BlockToRowCol(Block, Index: integer): TPoint;
var
VX, VY: integer;
begin
// Block 0..8, Index 0..8
// Result.X = Row 0..8, Result.Y = Col 0..8
VX:= 0;
VY:= 0;
case Block of
0: begin VX:= 0; VY:= 0; end;
1: begin VX:= 3; VY:= 0; end;
2: begin VX:= 6; VY:= 0; end;
3: begin VX:= 0; VY:= 3; end;
4: begin VX:= 3; VY:= 3; end;
5: begin VX:= 6; VY:= 3; end;
6: begin VX:= 0; VY:= 6; end;
7: begin VX:= 3; VY:= 6; end;
8: begin VX:= 6; VY:= 6; end;
end;
with Result do
begin
X:= 0;
Y:= 0;
case Index of
0: begin X:= VY; Y:= VX; end;
1: begin X:= VY; Y:= VX+1; end;
2: begin X:= VY; Y:= VX+2; end;
3: begin X:= VY+1; Y:= VX; end;
4: begin X:= VY+1; Y:= VX+1; end;
5: begin X:= VY+1; Y:= VX+2; end;
6: begin X:= VY+2; Y:= VX; end;
7: begin X:= VY+2; Y:= VX+1; end;
8: begin X:= VY+2; Y:= VX+2; end;
end;
end;
end;
procedure TForm1.SetSudokuBlock(I: integer; Numbers: TIntegerList);
var
Result: TIntegerList;
J, N, Index: integer;
T: TPoint;
A, B, C: boolean;
begin
Result:= TIntegerList.Create;
try
Result.FillUp(9);
N:= 0;
repeat
A:= true;
B:= true;
C:= true;
for J:= 0 to 8 do
begin
Index:= FPermutList.Item[N*9+J];
Result.Item[J]:= Numbers.Item[Index];
T:= BlockToRowCol(I, J);
A:= A and FRow[T.X].CanHaveValue(Result.Item[J]);
B:= B and FCol[T.Y].CanHaveValue(Result.Item[J]);
C:= C and FBlock[I].CanHaveValue(Result.Item[J]);
end;
Inc(N);
until (A and B and C);
for J:= 0 to 8 do
begin
T:= BlockToRowCol(I, J);
FRow[T.X].Item[T.Y]:= Result.Item[J];
FCol[T.Y].Item[T.X]:= Result.Item[J];
FBlock[I].Item[J]:= Result.Item[J];
end;
finally
Result.Free;
end;
end;
procedure TForm1.BuildSudoku;
var
Numbers: TIntegerList;
I, J: integer;
begin
Numbers:= TIntegerList.Create;
try
Numbers.FillUp(9, 1, 1);
Numbers.Mix;
SudokuNull;
for I:= 0 to 8 do // Blöcke
SetSudokuBlock(I, Numbers);
finally
Numbers.Free;
end;
end;
|
|
Zitat
|