![]() |
Mal wieder ein Sudoku Problem
Hi an alle :hi:
Ich versuch gerade ein Sudoku-Lösungsprogram zu erstellen und ich hänge gerade an der Fehlerprüfung. Für die Horzontale/Vertikale Prüfung habe ich ne Menge genommen in die die reihen über 2 for schleien eingelesen und überprüft werden ob die einzulesende Zahl schon in der Menge enthalten ist wenn ja soll ein fehler ausgegeben werde - das klapp schon Mein problem ist jetzt wie löse ich das für die Sub-array's also die 3x3 Felder aus dem das ganze feld zusammen gesetzt ist. also mir wüde es schon reichen wenn mir einer sagen kann wie ich aus einem Großen Array mit 9x9 Feldern 9 kleine machen kann mit 3x3 feldern Also schon mal nen riesen dankeschön und noch ein schönes WE an alle Olli :gruebel: |
Re: Mal wieder ein Sudoku Problem
Zitat:
|
Re: Mal wieder ein Sudoku Problem
Hallo Olli,
wenn es mit mod nicht klappt, dann probiere es mal mit div. Grüße vom marabu |
Re: Mal wieder ein Sudoku Problem
:wiejetzt: naja aber wie würdet ihr das genau machen?
vielleicht nen kleinen programm ausschnitt ich seh denke ich den wald vor lauter bäumen nicht mehr :wall: |
Re: Mal wieder ein Sudoku Problem
Du kombinierst einfach Ollis genialen Einfall und meinen Schwachsinn und dann erhältst du sowas:
Delphi-Quellcode:
Freundliche Grüße vom marabu
function BigToSmall(
iBigCol, iBigRow: Integer; var iBlockCol, iBlockRow, iSmallCol, iSmallRow: Integer ): Boolean; begin Result := (iBigCol in [0..8]) and (iBigRow in [0..8]); if Result then begin iBlockCol := iBigCol div 3; iBlockRow := iBigRow div 3; iSmallCol := iBigCol mod 3; iSmallRow := iBigRow mod 3; end; end; function SmallToBig( iBlockCol, iBlockRow, iSmallCol, iSmallRow: Integer; var iBigCol, iBigRow: Integer ): Boolean; begin Result := (iBlockCol in [0..2]) and (iBlockRow in [0..2]) and (iSmallCol in [0..2]) and (iSmallRow in [0..2]); if Result then begin iBigCol := 3 * iBlockCol + iSmallCol; iBigRow := 3 * iBlockRow + iSmallRow; end; end; |
Re: Mal wieder ein Sudoku Problem
:shock: :? °-° schon mal thx aber ich glaub ich bin zu doof um das gard zu verstehen :pale:
oder es ist nich das was ich brauche - oder von beidem etwas vielleicht hab ich mich einfach falsch ausgedrückt ich hab nen Sudokufeld (StringGrid) und das habe ich über 2 for schleifen in ein array eingelesen :
Delphi-Quellcode:
geht es geschickter die 9ner blöcke auszulesen als:
for y:=0 to CMaxSudokuIndex do
for x:=0 to CMaxSudokuIndex do begin if StrGrid.Cells[x,y] <> '' then main_array[x,y]:=StrToInt(StrGrid.Cells[x,y]); ... end; (eigentlich ne doofe frage weil das muss einfacher gehen :P
Delphi-Quellcode:
und wenn deine Lösung die du soeben gepostet hast das problem lösen sollte dann entschuldige ich mich vielmals!!! aber ich bin noch ein noobie was programmieren angeht
for j:=0 to 2 do
for i:=0 to 2 do begin if StrGrid.Cells[i,j] <> '' then Sub_array[i,j]:=StrToInt(StrGrid.Cells[x,y]); ... end; for j:=3 to 5 do for i:=0 to 2 do begin if StrGrid.Cells[i,j] <> '' then Sub_array[i,j]:=StrToInt(StrGrid.Cells[x,y]); ... end; ... for j:=6 to 8 do for i:=0 to 2 do begin if StrGrid.Cells[i,j] <> '' then Sub_array[i,j]:=StrToInt(StrGrid.Cells[x,y]); ... end; ... |
Re: Mal wieder ein Sudoku Problem
Versuch dich doch mal in marabu's Lösung einzulesen. Das wichtigste als Einsteiger ist Ausdauer. Wir wollen dir nämlich nicht dein Programm schreiben, sondern dir beibringen wie du dein Programm schreibst - und am besten noch so, daß du noch andere Dinge daraus lernst ;)
Nimm dir mal etwas Zeit und schaue dir den Code an. Versuche ihn durchzugehen - meinetwegen auch im Debugger - und wenn du dann noch keine Lösung für dein Problem siehst, kommst du wieder. |
Re: Mal wieder ein Sudoku Problem
das hab ich schon
hab den quellcode in Delphi drin aber ich weiß nich was marabu mit iblockCol/Row meint das andere dürften die zeilen- und spalenanzahlen sein einmal für das große array und einmal für ein kleines und ich will auch nich das mir einer das proramm schreibt dann würde ich eines der fertigen die hier im Forum sind nehemen aber ich will ja auch etwas daraus lernen nur komm ich leider nicht weiter und ich finde dafür ist das Forumm echt super!!! |
Re: Mal wieder ein Sudoku Problem
Okay, gehen wir mal durch marabu's Code ;) ... beachte die Kommentarzeilen!
Delphi-Quellcode:
Und jetzt gucken wir, wie das 9x9-Feld aussieht, wenn wir es nach den oben in den Kommentaren in eckige Klammern gesetzten Ziffern aufschlüsseln:
// Col steht für "column" - also Spalte
// Row steht für Zeile // Konvertiert den den Spalten- und Zeilenindex innerhalb des großen // 9x9-Feldes in den jeweiligen Index des 3x3-Blocks und innerhalb des // 3x3-Blocks function BigToSmall( // iBigCol und iBigRow sind die Indeces innerhalb des großen 9x9-Feldes iBigCol, iBigRow: Integer; // variable Parameter welche mit Werten gefüllt werden var iBlockCol, iBlockRow, iSmallCol, iSmallRow: Integer ): Boolean; begin // Überprüfung ob sich die Eingabewert im gültigen Bereich befinden Result := (iBigCol in [0..8]) and (iBigRow in [0..8]); // Füllen der variablen Parameter mit den Werten if Result then begin // "Blockspalte" ist der Index der Spalte eines 3x3er Blocks [1] iBlockCol := iBigCol div 3; // "Blockzeile" ist der Index der Zeile eines 3x3er Blocks [1] iBlockRow := iBigRow div 3; // "kleine Spalte" ist der Index der Spalte innerhalb des 3x3er Blocks [2] iSmallCol := iBigCol mod 3; // "kleine Zeile" ist der Index der Zeile innerhalb des 3x3er Blocks [2] iSmallRow := iBigRow mod 3; end; end; // Gegenteil der obigen Funktion BigToSmall() function SmallToBig( iBlockCol, iBlockRow, iSmallCol, iSmallRow: Integer; var iBigCol, iBigRow: Integer ): Boolean; begin // Überprüfung ob sich die Eingabewert im gültigen Bereich befinden Result := (iBlockCol in [0..2]) and (iBlockRow in [0..2]) and (iSmallCol in [0..2]) and (iSmallRow in [0..2]); // Füllen der variablen Parameter mit den Werten if Result then begin // Spalte innerhalb des 9x9-Feldes anhand der Eingabe berechnen iBigCol := 3 * iBlockCol + iSmallCol; // Zeile innerhalb des 9x9-Feldes anhand der Eingabe berechnen iBigRow := 3 * iBlockRow + iSmallRow; end; end; Spaltenindeces: iBlockCol nach [1]
Code:
Zeilenindeces: iBlockRow nach [1]
0 0 0 1 1 1 2 2 2
0 0 0 1 1 1 2 2 2 0 0 0 1 1 1 2 2 2 0 0 0 1 1 1 2 2 2 0 0 0 1 1 1 2 2 2 0 0 0 1 1 1 2 2 2 0 0 0 1 1 1 2 2 2 0 0 0 1 1 1 2 2 2 0 0 0 1 1 1 2 2 2
Code:
Spaltenindeces: iSmallCol nach [2]
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
Code:
Zeilenindeces: iSmallRow nach [2]
0 1 2 0 1 2 0 1 2
0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2
Code:
Vielleicht kannst du jetzt begreifen, was gemeint war ...
0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 |
Re: Mal wieder ein Sudoku Problem
:pale: hi
nein nicht wirklich!!! Ich find das super lieb das du dir die mühe gemacht hast aber groß weitergeholfen hat es mir nicht was das programm im großen und ganzen macht ist mir schon klar aber im großen und ganzen hat es mir leider auch nich viel geholfen Leider hat es mich nicht weiter gebracht ein Sudoku-lösungrogramm rekursiv zu lösen ich habe die überprüfung jetzt anders gelößt aber insgesamt hat es mir nicht geholfen das es bei mir nur den fall für ein 9x9 feld abdeckt (und das eher schlecht als recht) das ganze sieht so bei mir aus:
Delphi-Quellcode:
das dürfte nicht die beste lösug sein aber die die ich selbst erarbeitet habe *eigentlich ganz glücklich*
function Sub_Array_check(array_var:TArray):boolean; // array_var: array[0..8,0..8] of integer
var x,y,i,j:integer; Ergebnismenge:TEingabemenge; check_var:boolean; begin check_var:=true; x:=0; y:=0; Ergebnismenge:=[]; for j:=x to x+CSubSudokuLaenge-1 do //CSubSudokuLaenge=3 for i:=y to y+CSubSudokuLaenge-1 do begin Sub_array[i,j]:=array_var[i,j]; if (not(Sub_array[i,j] in Ergebnismenge) or (Sub_array[i,j] = 0)) then Ergebnismenge:=Ergebnismenge + [Sub_array[i,j]] else check_var:=false; if ((i=CSubSudokuLaenge-1) or (i=CSubSudokuLaenge+2)) or (i=CSubSudokuLaenge+5) then begin x:=x+3; y:=0 end; end; Sub_array_check:=check_var; end; nur leider bin ich der lösung des problems ein Lösungsprogramm zu erstellen nich viel weiter gekommen da ich nich wirklich weiß wie ich das ganze rekursiv lösen kann und dann gibt es da noch das problem die felder zu füllen da hab ich noch nich den geringsten schimmer wie ich das anstellen könnte also wenn ihr nette ideen habt dann immer her damit und für die bisherige hilfe schon mal ein RIESEN dankescön!!! Olli |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:06 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz