StackOverflow nach 27 runs


  • Mod

    Zhorky schrieb:

    Nein, ich fülle es eigentlich komplett aber nach 1/3 kommt der StackOverflow.
    Und doch es entsteht ja ein komplett ausgefülltes sudoku. In diesem werde ich dann beliebig viele Zahlen löschen

    Ich glaube du hast nicht verstanden, was Michael E. meinte: Du kannst nicht (beziehungsweise nur mit praktisch unschaffbar großem Aufwand) ein Sudoku durch zufälliges Vorgehen erschaffen. Da läufst du praktisch unendlich oft (ist das vielleicht das Problem?) in unlösbare Stellungen bevor du ein komplettes Gesamtsudoku erzeugst. Sudokus erzeugen ist schwieriger als lösen! Bessere Algorithmen als zufälliges Vorgehen findest du im Internet. Als Basis für diese Algorithmen benötigst du meistens einen bereits funktionierenden Solver, der dann gezielt aus einer einfachen Anfangskonfiguration (ein oder zwei Kästchen kann man noch zufällig erzeugen) den Rest löst.



  • Michael E. schrieb:

    Zhorky schrieb:

    Nein, ich fülle es eigentlich komplett aber nach 1/3 kommt der StackOverflow.
    Und doch es entsteht ja ein komplett ausgefülltes sudoku. In diesem werde ich dann beliebig viele Zahlen löschen

    Ah, dann kommen wir der Sache schon näher 🙂 Führe deinen Algorithmus einmal manuell aus, d.h. füge Stelle für Stelle eine zufällige Zahl an, die passt. Irgendwann wirst du mit sehr hoher Wahrscheinlichkeit feststellen, dass du an eine Position gelangst, an die keine der neun möglichen Ziffern passt. Das bedeutet, dass deine Vorgehensweise nicht funktioniert.

    Ja das ist mir schon vorher aufgefallen.
    Nur mich wundert es, dass er es bis zum Punkt 27 Macht wie er soll aber sozusagen ab der 4. Reihe anfängt mit Schwachsinn machen.

    Im Beispiel:
    758|431|629
    913|267|485
    642|985|317
    ----+----+----
    ?xx|xxx|xxx
    xxx|xxx|xxx
    xxx|xxx|xxx
    ----+----+----
    xxx|xxx|xxx
    xxx|xxx|xxx
    xxx|xxx|xxx

    Sollte es ja kein Problem sein für "?" eine Zahl einzusetzen.
    Dies tut er aber nicht, weil Bahnhof


  • Mod

    Zhorky schrieb:

    Sollte es ja kein Problem sein für "?" eine Zahl einzusetzen.
    Dies tut er aber nicht, weil Bahnhof

    Messerscharfe Schlussfolgerung: Dann wird da wohl ein Fehler sein 🙂 .
    Die Verdächtigen sind Randomize und check. Vermutlich check. Aus irgendeinem Grund ist das immer true.
    Daher:
    a) Selbsthilfe
    - Unter Linux mal valgrind nutzen mit allen Tests. Unter Windows gibt es bestimmt was ähnliches.
    - Vielleicht ein paar Debugausgaben
    - Debugmodi des Compilers aktivieren. Bounds checking und solchen Kram, eventuell selber ein paar assertions setzen.
    b) Hilfe zur Hilfe durch das Forum
    - Dritten Link in meiner Signatur durchlesen.
    - Minimales Beispiel schrittweise erstellen, bei jedem Schritt prüfen, ob der Fehler noch vorhanden ist.
    - Dann dieses compilierbare Minimalbeispiel hier zeigen.



  • Zhorky schrieb:

    Sollte es ja kein Problem sein für "?" eine Zahl einzusetzen.

    Dessen bin ich mir bewusst. Aber was bringt es, hier noch aufwendig den Fehler zu suchen, wenn du deinen Code eh wegwirfst, weil der Algorithmus nicht funktioniert?



  • Ich hatte mal einen Sudokugenerator programmiert der auf diese Weise funktioniert hat, leider ist der mir durch nen Festplattendefekt abhanden gekommen...
    Ich persönlich glaube ja eher fast dass ich an der Überprüfung der Blöcke einen Fehler habe.

    Der Code dafür sieht so aus:

    if ((x<3)&&(x>=0)) {
    		if ((y<3)&&(y>=0)) { /
    			for (int yy=0; yy<3; yy++) {
    				for (int xx=0; xx<3; xx++) {
    					if (ofield[xx][yy]==number) {
    						return true;
    					}
    				}
    			}
    		}
    		if ((y<6)&&(y>=3)) { 
    			for (int yy=3; yy<6; yy++) {
    				for (int xx=0; xx<3; xx++) {
    					if (ofield[xx][yy]==number) {
    						return true;
    					}
    				}
    			}
    		}
    		if ((y<9)&&(y>=6)) {
    			for (int yy=6; yy<9; yy++) {
    				for (int xx=0; xx<3; xx++) {
    					if (ofield[xx][yy]==number) {
    						return true;
    					}
    				}
    			}
    		}
    	}
    	if ((x<6)&&(x>=3)) {
    		if ((y<3)&&(y>=0)) { 
    			for (int yy=0; yy<3; yy++) {
    				for (int xx=0; xx<3; xx++) {
    					if (ofield[xx][yy]==number) {
    						return true;
    					}
    				}
    			}
    		}
    		if ((y<6)&&(y>=3)) { 
    			for (int yy=3; yy<6; yy++) {
    				for (int xx=0; xx<3; xx++) {
    					if (ofield[xx][yy]==number) {
    						return true;
    					}
    				}
    			}
    		}
    		if ((y<9)&&(y>=6)) {
    			for (int yy=6; yy<9; yy++) {
    				for (int xx=0; xx<3; xx++) {
    					if (ofield[xx][yy]==number) {
    						return true;
    					}
    				}
    			}
    		}
    	}
    	if ((x<9)&&(x>=6)) {
    		if ((y<3)&&(y>=0)) { 
    			for (int yy=0; yy<3; yy++) {
    				for (int xx=0; xx<3; xx++) {
    					if (ofield[xx][yy]==number) {
    						return true;
    					}
    				}
    			}
    		}
    		if ((y<6)&&(y>=3)) { 
    			for (int yy=3; yy<6; yy++) {
    				for (int xx=0; xx<3; xx++) {
    					if (ofield[xx][yy]==number) {
    						return true;
    					}
    				}
    			}
    		}
    		if ((y<9)&&(y>=6)) { 
    			for (int yy=6; yy<9; yy++) {
    				for (int xx=0; xx<3; xx++) {
    					if (ofield[xx][yy]==number) {
    						return true;
    					}
    				}
    			}
    		}
    	}
    	return false; 
    }
    

    @SeppJ: Das mit den einzelschritten werd ich gleich mal probieren


  • Mod

    😮 Das SCHREIT ja geradezu nach einem Tippfehler! Den zu suchen nehme ich dir aber nicht ab, da du selber schuld bist, wenn du jede Bedingung einzeln aufschreibst. Wie wäre es mit etwas Abstraktion? Ein paar gut gewählte Funktionen und schon schrumpfen deine 90 Zeilen Codewiederholungen auf übersichtliche 10 Zeilen zusammen. In denen findet man dann auch schnell eventuelle Fehler.
    Vorschlag: Funktion zum Prüfen der Zeile, Funktion zum Prüfen der Spalte, Funktion zum Prüfen des Kästchens. Die ersten beiden sind einfach jeweils eine einfache Schleife, die dritte ist eine verschachtelte Doppelschleife. Wenn alle drei Funktionen nix finden, dann gibt es keine Dublette.

    Zhorky schrieb:

    Ich hatte mal einen Sudokugenerator programmiert der auf diese Weise funktioniert hat, leider ist der mir durch nen Festplattendefekt abhanden gekommen...

    Nichts gegen dich, aber das ist ungefähr so glaubwürdig als würdest du behaupten, mal ein Perpetuum Mobile gebastelt zu haben, das du dann auf den Müll geworfen hast, als es langweilig wurde. Solch ein Programm würde selbst mit recht optimistischen Abschätzungen 10-20 Minuten, eher mehrere Stunden benötigen.



  • xx läuft unabhängig vom Wert von x immer von 0 bis 2.



  • Michael E. schrieb:

    xx läuft unabhängig vom Wert von x immer von 0 bis 2.

    Vielen Dank erstmal dafür... Jetz muss ich sagen generiert er zumindest ein wenig besser. Jetz hört er nach 5-70 runs auf 😮 .

    Und ich habe soeben ausserdem ein Programm gefunden was so ähnlich läuft wie meins.
    http://www.tutorials.de/c-c/327637-sudoku-c.html

    Er überprüft nur seinen Block anders (Mit Schleifen *hust*) und befüllt seine Felder anders Blockweise. Das befüllen sollte jedoch keinen unterschied machen.


  • Mod

    Zhorky schrieb:

    Jetz hört er nach 5-70 runs auf 😮 .

    Im Sinne von "er schafft ein gültiges(!) Sudoku"? Da bin ich jetzt aber doch etwas baff und muss noch mal abschätzen, wie wahrscheinlich das ist. Was genau ist bei dir denn ein "run"?



  • Ein run = Eine Zahl, und ja es ist ein gültiges Sudoku 😉


  • Mod

    Zhorky schrieb:

    Ein run = Eine Zahl, und ja es ist ein gültiges Sudoku 😉

    Wie kann er dann nach weniger als 81 Zahlen aufhören? Oder ist aufhören == abstürzen?



  • SeppJ schrieb:

    Zhorky schrieb:

    Ein run = Eine Zahl, und ja es ist ein gültiges Sudoku 😉

    Wie kann er dann nach weniger als 81 Zahlen aufhören? Oder ist aufhören == abstürzen?

    Nein ich meinte das Zitierte Programm, welches so läuft.
    Meins bleibt bei den Stackoverflows nach beliebigen Schleifendurchläufen obwohl man durchaus Zahlen einfügen könnte.


Anmelden zum Antworten