Rekursiver Sudokulöser
Übersicht
BlitzBasic
Codearchiv|
|
GoodjeeBetreff: Rekursiver Sudokulöser |
Antworten mit Zitat |
|---|---|---|
|
ich weiß, es gibt schon 2 Sudokulöser im codearchiv, aber die sind alle nicht rekursiv und nicht so kurz wie meiner...
ich glaube meiner läuft auch relativ schnell ohne debug und mit drawmode 0 wenn man das sudoku löscht kann man sogar eigene, aber fertige, erstellen *g* Code: [AUSKLAPPEN] Graphics 180,180,32,2
SetBuffer BackBuffer() Dim sudoku(8,8,1) ;speichert das Sudoku, 0:werte,1:fest oder nicht Global ready ;Sudoku ist fertig gelöst oder nicht Global drawmode=0 ;0:garnicht,1:immer wenn neuer richtiger wert,2:immer ;laden Restore feld For zy=0 To 8 For zx=0 To 8 Read sudoku(zx,zy,0) If sudoku(zx,zy,0)<>0 Then sudoku(zx,zy,1)=1 Next Next ;ausgeben draw() ;Lösen If check(0,0) Then RuntimeError("unlösbar") ;ausgeben Repeat draw() Until KeyHit(1) End Function check(x,y) Local val,a ;berechnen der korrekten x position If x>8 Then x=0:y=y+1 ;weitergehen zum nächsten freien kästchen While sudoku(x,y,1)=1 x=x+1 If x>8 Then y=y+1:x=0 If y>8 Then ready=1:Return False EndIf Wend ;kästchen füllen For val=1 To 9 DebugLog("x:"+x+" / y:"+y+" tested: "+val) sudoku(x,y,0)=val If drawmode=2 Then draw() ;If nrone Then Stop If fit(x,y,val) Then ;falls der Wert passt If drawmode=1 Then draw() If x=8 And y=8 Then ready=1 Return False ;wenn letztes kästchen beenden EndIf a=check(x+1,y) ;nächstes kästchen checken If Not a Then Return False ;wenn "endmessage" kommt beenden EndIf Next ;wenn keine lösung beenden ->letztes kästchen kriegt anderen wert sudoku(x,y,0)=0 Return True End Function Function fit(x,y,val);gibt zurück, ob eine zahl in ein kästchen passt Local startx,starty,tx,ty ;waagerechte übereinstimmungen suchen For tx=0 To 8 If sudoku(tx,y,0)=val And tx<>x Then DebugLog "waag "+tx:Return False Next ;senkrecht übereinstimmungen suchen For ty=0 To 8 If sudoku(x,ty,0)=val And ty<>y Then DebugLog "senk "+ty:Return False Next ;in den kästchen übereinstimmungen suchen If x<3 And y<3 Then startx=0:starty=0 If x>2 And x<6 And y<3 Then startx=3:starty=0 If x>5 And y<3 Then startx=6:starty=0 If x<3 And y>2 And y<6 Then startx=0:starty=3 If x>2 And x<6 And y>2 And y<6 Then startx=3:starty=3 If x>5 And y>2 And y<6 Then startx=6:starty=3 If x<3 And y>5 Then startx=0:starty=6 If x>2 And x<6 And y>5 Then startx=3:starty=6 If x>5 And y>5 Then startx=6:starty=6 For tx=0 To 2 For ty=0 To 2 If sudoku(tx+startx,ty+starty,0)=val And tx+startx<>x And ty+starty<>y Then DebugLog("kästchen"):Return False Next Next ;wenn keine übereinstimmung gefunden Return True End Function Function draw() Local zx,zy Cls For zy=0 To 8 For zx=0 To 8 Color 200,0,0 If ready Then Color 0,200,0 If sudoku(zx,zy,1) Then Color 0,0,200 If sudoku(zx,zy,0) <> 0 Then Text 5+zx*20,3+zy*20,sudoku(zx,zy,0) Else Text 5+zx*20,3+zy*20,"X" EndIf Next Next Flip 0 End Function .feld ;sudoku von wikipedia Data 5,3,0,0,7,0,0,0,0 Data 6,0,0,1,9,5,0,0,0 Data 0,9,8,0,0,0,0,6,0 Data 8,0,0,0,6,0,0,0,3 Data 4,0,0,8,0,3,0,0,1 Data 7,0,0,0,2,0,0,0,6 Data 0,6,0,0,0,0,2,8,0 Data 0,0,0,4,1,9,0,0,5 Data 0,0,0,0,8,0,0,7,9 ;sudoku von http://sudoku.zeit.de/sudoku/kunden/die_zeit/ Data 0,0,0,3,7,0,0,0,0 Data 0,5,0,0,0,0,1,3,4 Data 3,9,6,0,0,0,2,0,8 Data 6,0,1,0,0,0,7,0,0 Data 0,0,0,5,0,0,3,0,0 Data 0,3,7,8,9,1,4,0,0 Data 0,0,4,1,0,0,0,0,3 Data 0,6,0,0,4,2,0,0,9 Data 2,0,0,0,0,3,6,0,0 |
||
|
"Ideen sind keine Coladosen, man kann sie nicht recyclen"-Dr. House
http://deeebian.redio.de/ http://goodjee.redio.de/ |
||
- Zuletzt bearbeitet von Goodjee am Do, Aug 03, 2006 17:49, insgesamt 2-mal bearbeitet
Froggy |
Antworten mit Zitat |
|
|---|---|---|
|
EDIT: Das Sudoku von Wikipedia (http://de.wikipedia.org/wiki/Sudoku) kann es nicht lösen Nettes Programm. Ich hab mir die Freiheit genommen, es so zu verändern, dass man zuerst die vorgegebenen Zahlen eingeben muss und es dann mit Enter lösen lässt: Code: [AUSKLAPPEN] ;------------------------------------------------------------------------------------ ;INFORMATION ; ;An gewünschter Stelle die Maus gedrückt halten und die ;vom Sudoku vorgegebenen Zahlen eingeben (0 wird zu X). ;Enter drücken, Sudoku wird gelöst. ; ;Rote X: Nicht vorgegebene Zahlen ;Blaue Zahlen: Vorgegebene Zahlen ;Grüne Zahlen: Ermittelte Zahlen ;------------------------------------------------------------------------------------ Graphics 180,180,32,2 SetBuffer BackBuffer() Dim sudoku(8,8,1) ;speichert das Sudoku, 0:werte,1:fest oder nicht Global ready ;Sudoku ist fertig gelöst oder nicht Global drawmode=0 ;0:garnicht,1:immer wenn neuer richtiger wert,2:immer Repeat mx = MouseX():my=MouseY() If MouseDown(1) Then Taste = GetKey() If Taste >= 48 And Taste <= 57 Then Sudoku(Floor(mx/20),Floor(my/20),0) = Taste-48 Sudoku(Floor(mx/20),Floor(my/20),1) = 1 EndIf EndIf For i = 0 To 8 For j = 0 To 8 If sudoku(i,j,0) = 0 Then sudoku(i,j,1) = 0 Next Next draw() Until KeyHit(28) ;Lösen If check(0,0) Then RuntimeError("unlösbar") ;ausgeben Repeat draw() Until KeyHit(1) End Function check(x,y) Local val,a ;berechnen der korrekten x position If x>8 Then x=0:y=y+1 ;weitergehen zum nächsten freien kästchen While sudoku(x,y,1)=1 x=x+1 If x>8 Then y=y+1:x=0 Wend ;kästchen füllen For val=1 To 9 DebugLog("x:"+x+" / y:"+y+" tested: "+val) sudoku(x,y,0)=val If drawmode=2 Then draw() If fit(x,y,val) Then ;falls der Wert passt If drawmode=1 Then draw() If x=8 And y=8 Then ready=1 Return False ;wenn letztes kästchen beenden EndIf a=check(x+1,y) ;nächstes kästchen checken If Not a Then Return False ;wenn "endmessage" kommt beenden EndIf Next ;wenn keine lösung beenden ->letztes kästchen kreigt anderen wert sudoku(x,y,0)=0 Return True End Function Function fit(x,y,val);gibt zurück, ob eine zahl in ein kästchen passt Local startx,starty,tx,ty ;waagerechte übereinstimmungen suchen For tx=0 To 8 If sudoku(tx,y,0)=val And tx<>x Then DebugLog "waag "+tx:Return False Next ;senkrecht übereinstimmungen suchen For ty=0 To 8 If sudoku(x,ty,0)=val And ty<>y Then DebugLog "senk "+ty:Return False Next ;in den kästchen übereinstimmungen suchen If x<3 And y<3 Then startx=0:starty=0 If x>2 And x<6 And y<3 Then startx=3:starty=0 If x>5 And y<3 Then startx=6:starty=0 If x<3 And y>2 And y<6 Then startx=0:starty=3 If x>2 And x<6 And y>2 And y<6 Then startx=3:starty=3 If x>5 And y>2 And y<6 Then startx=6:starty=3 If x<3 And y>5 Then startx=0:starty=6 If x>2 And x<6 And y>5 Then startx=3:starty=6 If x>5 And y>5 Then startx=6:starty=6 For tx=0 To 2 For ty=0 To 2 If sudoku(tx+startx,ty+starty,0)=val And tx+startx<>x And ty+starty<>y Then DebugLog("kästchen"):Return False Next Next ;wenn keine übereinstimmung gefunden Return True End Function Function draw() Local zx,zy Cls For zy=0 To 8 For zx=0 To 8 Color 200,0,0 If ready Then Color 0,200,0 If sudoku(zx,zy,1) Then Color 0,0,200 If sudoku(zx,zy,0) <> 0 Then Text 5+zx*20,3+zy*20,sudoku(zx,zy,0) Else Text 5+zx*20,3+zy*20,"X" EndIf Next Next Flip 0 End Function |
||
|
|
Triton |
Antworten mit Zitat |
|---|---|---|
| Auch das kann das von Wiki nicht lösen.. | ||
| Coding: silizium-net.de | Portfolio: Triton.ch.vu | ||
|
|
PowerProgrammer |
Antworten mit Zitat |
|---|---|---|
|
Ich habs mit einem aus der Zeitung versucht, ging prima. War in Null Komma Nichts fertig. Als ich dann versucht habe, ein leeres Sudoku zu lösen, hat der ewig gebraucht Großes Lob von mir! |
||
| www.xairro.com Alles für Webmaster und Programmierer! Es gibt mehr als bloß einen Counter! | ||
Blood Brother |
Antworten mit Zitat |
|
|---|---|---|
|
Zwar in Delphi Programmiert, aber ich denke der Code lässt sich relativ Problemlos auch für Blitz umsetzen.
Hier meine rekursive Lösung: Code: [AUSKLAPPEN] function Possibilities(feld:tSudoku; pos: tPosition; Zahl: Integer):Bool; var I,J,A,B,C,D: Integer; begin Result:=True; for I:=1 to 9 do begin if feld[pos[1],I]=Zahl then Result:=False; if feld[I,pos[2]]=Zahl then Result:=False; end; If pos[1]<=3 then begin A:=1; B:=3; end; If (pos[1]>=4) and (pos[1]<=6) then begin A:=4; B:=6; end; If pos[1]>=7 then begin A:=7; B:=9; end; If pos[2]<=3 then begin C:=1; D:=3; end; If (pos[2]>=4) and (pos[2]<=6) then begin C:=4; D:=6; end; If pos[2]>=7 then begin C:=7; D:=9; end; for I:=A to B do begin for J:=C to D do begin If feld[I,J]=Zahl then Result:=False; end; end; end; function NextPosition(feld: tSudoku): tPosition; var I,J: Integer; begin for I:=1 to 9 do begin for J:=1 to 9 do begin If feld[I,J]=0 then begin Result[1]:=I; Result[2]:=J; Exit; end; end; end; Result[1]:=0; Result[2]:=0; end; function Loesen(feld: tSudoku):bool; var workfield: tSudoku; position: tPosition; moeglichkeit: tPossibilities; I: Integer; Ausgabe: bool; antwort: word; begin Result:=False; workfield:=feld; position:=NextPosition(workfield); current_time:=MilliSecondOfTheDay(Time()); If current_time-start_time>=2000 then begin abbruch:=True; antwort:=MessageDlg('Achtung: Die Berechnung dauert zu lange, das eingebene SuDoKu Rätsel hat wahrscheinlich keine gültige Lösung!',mtWarning,[mbAbort,mbRetry],0); if antwort=mrRetry then begin abbruch:=False; start_time:=MilliSecondOfTheDay(Time()); end; if antwort=mrAbort then begin abbruch:=True; Result:=True; Exit; end; end; if (position[1]=0) and (position[2]=0) then begin Result:=True; fertiges_feld:=workfield; Exit; end; for I:=1 to 9 do begin moeglichkeit[I]:=Possibilities(workfield,position,I); end; for I:=1 to 9 do begin if moeglichkeit[I]=True then begin workfield[position[1],position[2]]:=I; Ausgabe:=Loesen(workfield); if (Ausgabe=True) or (abbruch=True) then begin Result:=True; Exit; end; end; end; end; Exe kann man hier laden: http://home.arcor.de/andivk/st...loeser.zip Und meins kann auch das SuDoKu von Wikipedia lösen Gruß Blood Brother |
||
|
|
Goodjee |
Antworten mit Zitat |
|---|---|---|
|
Triton hat Folgendes geschrieben: Auch das kann das von Wiki nicht lösen..
hata das schonmal einer gelöst??? edit: ich glaube es gibt probs wenn im ersten feld schon was steht... edit2 doch net... |
||
|
"Ideen sind keine Coladosen, man kann sie nicht recyclen"-Dr. House
http://deeebian.redio.de/ http://goodjee.redio.de/ |
||
- Zuletzt bearbeitet von Goodjee am Mi, Aug 02, 2006 11:52, insgesamt einmal bearbeitet
|
|
D2006Administrator |
Antworten mit Zitat |
|---|---|---|
|
Goodjee hat Folgendes geschrieben: hata das schonmal einer gelöst???
Die Lösung steht auf Wikipedia. Einfach mal das Bild anklicken |
||
|
Intel Core i5 2500 | 16 GB DDR3 RAM dualchannel | ATI Radeon HD6870 (1024 MB RAM) | Windows 7 Home Premium
Intel Core 2 Duo 2.4 GHz | 2 GB DDR3 RAM dualchannel | Nvidia GeForce 9400M (256 MB shared RAM) | Mac OS X Snow Leopard Intel Pentium Dual-Core 2.4 GHz | 3 GB DDR2 RAM dualchannel | ATI Radeon HD3850 (1024 MB RAM) | Windows 7 Home Premium Chaos Interactive :: GoBang :: BB-Poker :: ChaosBreaker :: Hexagon :: ChaosRacer 2 |
||
|
|
Goodjee |
Antworten mit Zitat |
|---|---|---|
| oh...na dann wird sich der fehler ja schnell finden...ich tippe auf einen bug in der fix funktion | ||
|
"Ideen sind keine Coladosen, man kann sie nicht recyclen"-Dr. House
http://deeebian.redio.de/ http://goodjee.redio.de/ |
||
|
|
Goodjee |
Antworten mit Zitat |
|---|---|---|
|
sry für doppelpost, aber:
Es geht jetzt, geänderte version hochgeladen. Als Beweis das Sudoku von Wikipedia beigelegt |
||
|
"Ideen sind keine Coladosen, man kann sie nicht recyclen"-Dr. House
http://deeebian.redio.de/ http://goodjee.redio.de/ |
||
|
|
SchnittlauchUnkraut |
Antworten mit Zitat |
|---|---|---|
|
Bei mir gehts immer noch nicht
EDIT:Geht doch |
||
| Ich wars nicht. | ||
- Zuletzt bearbeitet von Schnittlauch am Fr, Aug 04, 2006 13:22, insgesamt einmal bearbeitet
|
|
Goodjee |
Antworten mit Zitat |
|---|---|---|
|
musst auch das ausm ersten post nehmen nicht das von froggy....bei mir funzt es nämlich...das sudoku ist jetzt im code unten gespeichert
kann das mal noch einer testen??? |
||
|
"Ideen sind keine Coladosen, man kann sie nicht recyclen"-Dr. House
http://deeebian.redio.de/ http://goodjee.redio.de/ |
||
|
|
SoNenTyp |
Antworten mit Zitat |
|---|---|---|
| Jup jetzt gehts. | ||
|
Gruss Der Typ.
User posted image |
||
Übersicht
BlitzBasic
Codearchiv
Powered by phpBB © 2001 - 2006, phpBB Group
