Autor Beitrag
Grishnak
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 221

Windows XP Home
Delphi 7 PE, Delphi 2005 PE
BeitragVerfasst: Mo 19.09.05 11:48 
Ich habe einen kleinen Sudoku-Solver/Generator gebastelt. Schaut ihn euch doch bitte mal an! Er befindet sich noch im beta-Stadium, da ich noch nicht sicher bin, alle Fehler beseitigt zu haben (bekannt sind mir allerdings keine!). Das Generieren von Sudokus will ich aber noch "verfeinern"!
Einloggen, um Attachments anzusehen!
_________________
Mach' etwas idiotensicher und irgendjemand erfindet einen besseren Idioten!
AXMD
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 4006
Erhaltene Danke: 7

Windows 10 64 bit
C# (Visual Studio 2019 Express)
BeitragVerfasst: Mo 19.09.05 11:57 
Sodoku... hab ich schonmal wo gehört... eine Erklärung wäre trotzdem nicht schlecht; ich weiß immer gerne, was ich teste ;)

AXMD
Grishnak Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 221

Windows XP Home
Delphi 7 PE, Delphi 2005 PE
BeitragVerfasst: Mo 19.09.05 13:02 
Oops! Tja, wenn man sich soviel mit einem Thema beschäftigt, dann denkt man, andere wüssten sofort von was man spricht :roll: !

Guckst du hier!

_________________
Mach' etwas idiotensicher und irgendjemand erfindet einen besseren Idioten!
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: Mo 19.09.05 18:30 
Kannst du bitte eine exe einfügen. Hab keine Lust das zu compilieren.

_________________
"Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)
Grishnak Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 221

Windows XP Home
Delphi 7 PE, Delphi 2005 PE
BeitragVerfasst: Mo 19.09.05 18:59 
GTA-Place hat folgendes geschrieben:
Kannst du bitte eine exe einfügen. Hab keine Lust das zu compilieren.

Ich verstehe zwar nicht warum, aber bitte:
Einloggen, um Attachments anzusehen!
_________________
Mach' etwas idiotensicher und irgendjemand erfindet einen besseren Idioten!
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Di 20.09.05 16:55 
Hallo,

irgendwie habt Ihr noch nicht durchschaut, wie mein Programm das loest.
Ich bestimme fuer jedes Feld die freien Positionen.
Dann gehe ich Spalten und zeilenweise durch.
Zeilenweise:
Zeile 1 Spalte 1
Ich bestimme jetzt fuer alle Spalten der Zeile 1 ohne die eigene, die moeglichen Zahlen die dort eingesetzt werden koennen.
Dann bilde ich Diffenzmenge, von den Moeglichkeiten an Position 1,1 und eben dieser Vereinigungsmenge der Spaltenennachbarn.
Bleibt nur ein Wert darin , ist es der einzige der an Pos 1,1 passt-> eintragen
dasselbe fuer Spalten.
Und schon sind eindeutig loesbaren Spielfelder in TrivialFill geloest, alles ohne Rekursion.

Ich habe es quick and very dirty mal in Dein Programm gepinselt.
Stelle Dir einmal vor, Du willst Test-Sudoku #1.sud reduzieren, da das nicht geht dauert es weit ueber drei Minuten unter Volllast.
Bei meiner Vorgehensweise sind es ~8..10 Sekunden.
Das ist schon das 18-fache an Geschwindigkeit.

Gruss Horst
Einloggen, um Attachments anzusehen!
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Di 20.09.05 17:28 
Hallo,

Da muss unbedingt ein Begrenzer fuer die Versuchstiefe rein.
Ich habe nach der Reduktion 2 Positionen entfernt und auf loesen gedrueckt.
Bei 2.8Gbyte Auslagerungsdatei (1Gb Hauptspeicher) habe ich die Anwendung gekillt ( das dauert immer...)

Gruss Horst
Grishnak Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 221

Windows XP Home
Delphi 7 PE, Delphi 2005 PE
BeitragVerfasst: Mi 21.09.05 02:40 
Horst_H hat folgendes geschrieben:
Ich habe nach der Reduktion 2 Positionen entfernt und auf loesen gedrueckt.


Jaja, das kleine Biest sucht dann eben alle möglichen Lösungen zusammen! :twisted:
Wer allerdings nach dem Reduzieren noch Zahlen entfernt, sollte auch ein wenig Zeit mitbringen! :wink:

Anbei eine überarbeitete Version, die - so glaube ich - um einiges schneller ist!

Als nächstes nehme ich mir die Generierungs-Routine vor. Damit man einstellen kann, wie schwer der/die/das Sudoku werden soll!
Einloggen, um Attachments anzusehen!
_________________
Mach' etwas idiotensicher und irgendjemand erfindet einen besseren Idioten!
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 21.09.05 03:02 
Das ist schlecht in deiner Klasse:
ausblenden Delphi-Quelltext
1:
MainForm.ParanoiaLabel1.Caption := 'Test1 (' + IntToStr(col) + '/' + IntToStr(row) + ')';					

Ich könnte sie jetzt zum Beispiel nicht einfach nehmen und weiterverwenden ohne in deiner Klasse rumzubasteln.

Auch fehlen jegliche Ressourcenschutzblöcke.

Warum ist es kein Stringgrid, dann könnte man einfach über die Tastatur die Ziffern eingeben. Das per Drag and Drop ist doch mehr als umständlich.

Und ausdrucken wäre auch nicht schlecht.

Verdammt, warum fügt Alt+D keine Delphi-Tags ein, obwohl die Leiste angezeigt wird? Quote-Tags gehen. :roll:
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Mi 21.09.05 10:06 
Hallo,

generate und reduce wird erheblich schneller wenn man eine minimale Aenderung vornimmt:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TSudoku.Solve(SolutionList: TSolutionList;Anzahl:integer);
(* Schreibt maximal Anzahl Lösungsmöglichkeiten des Sudoku in eine Liste *)
var
  S: TSudoku;
  P: TPossibility;
  col, row, i: integer;
begin
  IF SolutionList.Count >= Anzahl then
    exit;
....

Dann kann man bei generate und reduce und ueberhaupt eine Schranke einbauen, die die Suche beschraenkt.
Bei reduce, generate eben Solve(SolutionList,2); einsetzen und bei den anderen z.B. 1000.

Wer braucht bei reduce schon tausende von Loesungen.
P.S.
Mein main.pas hat einen groben Fehler [col,r] mit [col,row] falsch eingesetzt so dass nur einzelne Werte einsetzen ueberhaupt funktionierte.
Dieses laeuft aber dennoch schneller, da die Bestimmung von isvalid {was anderes wird nicht zugelassen} und possilbleValue durch die Mengenoperationen so einfach ist.
Ich haette auch da abfragen sollen, ob je etwas eingefuegt wird, aber bei dem Tempo faellt das auch nicht auf. ;-)
Dadurch sind immer noch bei eigentlich eindeutigen Faellen Rekusionen noetig. Das ist schon unbefriedigend.

Gruss Horst

Moderiert von user profile iconTino: Code- durch Delphi-Tags ersetzt
Grishnak Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 221

Windows XP Home
Delphi 7 PE, Delphi 2005 PE
BeitragVerfasst: Mi 21.09.05 10:07 
@user profile iconLuckie:

wg. Ausgabe:
Ja, diese Ausgaben sind aber auch nur dazu da, zu sehen, ob sich noch was tut! (deshalb auch die Label-Bezeichnung 'Paranoia' :wink: ) Das kommt später raus!

wg. Schutzblöcke:
Auch hier muss ich auf später vertrösten. Problematik ist mir allerdings bekannt! :idea:

wg. StringGrid:
Mit einem TStringGrid habe ich herumprobiert, aber ich war damit nicht zufrieden! :roll:

wg. Ausdrucken:
Gute Idee! Werd' ich machen... :wink:

_________________
Mach' etwas idiotensicher und irgendjemand erfindet einen besseren Idioten!
Grishnak Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 221

Windows XP Home
Delphi 7 PE, Delphi 2005 PE
BeitragVerfasst: Mi 21.09.05 16:33 
So hier eine weitere Version:

- mit Eingabe einer maximalen Suchtiefe beim Lösen
- mit Eingabe eines Schwierigkeitsgrades beim Generieren

später mehr..!

@Horst_H: Danke für den Hinweis auf die Reduce-Routine!
Einloggen, um Attachments anzusehen!
Martin1966
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1068

Win 2000, Win XP
Delphi 7, Delphi 2005
BeitragVerfasst: Fr 23.09.05 09:01 
Hallo!

Nettes Programm. Wäre aber schön wenn man in dem "Grid" mit den Cursor-Tasten navgieren könnte um dann direkt eine Zahl einzutragen - also ohne Drag and Drop. Das ist wirklich etwas umständlich.

Schön wäre es auch wenn man beim Generieren einen Abbruch-Button zur Verfügung hat um den Vorgang abzubrechen.

Lg Martin
Grishnak Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 221

Windows XP Home
Delphi 7 PE, Delphi 2005 PE
BeitragVerfasst: Fr 23.09.05 11:00 
Da mir die Forderung von Horst_H nach "mehr Speed" keine Ruhe gelassen hat, habe ich die interne Darstellung komplett geändert - ich denke mit Erfolg! Das Programm sollte jetzt um einiges schneller laufen. (Allerdings können die .sud-Dateien der Vorgängerversionen nicht mehr geladen werden!)

Da meine anfängliche Meinung, dass das Programm so eigentlich fertig wäre, sich als falsch herausgestellt hat, habe ich auch die Versionsnummer geändert. Die aktuelle Version ist jetzt 0.9.3!

Die Generierung von Sudokus läuft (einwandfrei), allerdings bin ich hier noch am schrauben!

Eventuell überdenke ich auch noch die Steuerung (Stichwort: StringGrid statt Drag-n-Drop). Ebenfalls ausstehend ist eine Druck-Funktion sowie der Export als Text-Datei.
Einloggen, um Attachments anzusehen!
_________________
Mach' etwas idiotensicher und irgendjemand erfindet einen besseren Idioten!
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Fr 23.09.05 12:20 
Hallo,

Du hast ein Speicherleckproblem:
Du erzeugst wahnsinnig viele Objekte, aber gibst sie nicht mehr frei.
wenn du einfach eine FreeAndNil nach dem Test einfuehrst ist alles wieder gut.
8 MB konstant.
Statt immer zusaetzlich 6MB fuer jedes loesen des 15327.sud
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
{Zeile 374..}
For ...
  S:=TSudoku.Create;
  S.CopyFrom(self);
  S.FCells[col, row]:=$001 ShL i;{Einfuege neuen Probe Wert}
  minDepth:=S.Solve(Solutions, maxDepth-1, FindMulti)+1;
>>>freeAndNil(S);// Hau weg den .....
  if (minDepth > 0and (minDepth < Result) then Result:=minDepth;Deine


Gruss Horst

Moderiert von user profile iconraziel: Code- durch Delphi-Tags ersetzt
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: Fr 23.09.05 13:10 
user profile iconGrishnak hat folgendes geschrieben:
Ich verstehe zwar nicht warum, aber bitte:

Warum wohl? Vielleicht weil ich keine Lust habe, das erst zu entpacken, um
es dann mit Delphi öffnen und compilieren zu können. Ich will einfach nur gucken,
ob das Programm funktioniert und nicht wie der Source aussieht.

_________________
"Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)
Grishnak Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 221

Windows XP Home
Delphi 7 PE, Delphi 2005 PE
BeitragVerfasst: Fr 23.09.05 13:51 
@GTA-Place: War nicht böse gemeint, aber mir ist der Quelltext lieber. Er ist 1.) kleiner und schneller heruntergeladen und 2.) brauch' ich nicht noch nach Viren/Würmern/Trojanern zu suchen! Allerdings habe ich deine Bitte zu Herzen genommen und immer beides (Source + EXE) hochgeladen! :wink:

@Horst_H: Danke! Ich versuche zwar, darauf zu achten, alles was nicht mehr benötigt wird auch wieder freizugeben, aber da hat man schnell mal was übersehen! :idea:

_________________
Mach' etwas idiotensicher und irgendjemand erfindet einen besseren Idioten!
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Sa 24.09.05 14:20 
Hallo,

ich hatte da so eine Idee den Generator anders zu gestalten.
Ich erzeuge 3 mal eine beliebige Anordnung der n Zahlen in einem Quadrat.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
  procedure Wirbeln(var outW:tArrValue);
    var
    n_Fak,i : Cardinal;
    j,Pos,hilf : Tvalue;
    begin
    n_Fak := 1;
    For i := 0 to 8 do
      begin
      n_Fak := n_Fak*i;
      outW[i] := i+1;  //[1,2,3,4,5,6,7,8,9]
      end;
    (* Eine Kombination aus n! waehlen *)
    i := Random(n_Fak);
    (* Kombination erstellen *)
    For j := high(TValue) downto 1 do
      begin
      Pos := i mod j;
      i := i div j;
      If Pos<> j then
        begin
        hilf := outW[Pos];
        outW[Pos] := outW[j];
        outW[j] := hilf;
        end;
      end;

und trage diese Werte in die Quadrate 1,4,9
1,2,3
4,5,6
7,8,9
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
{consqr= 3;
ConSide = consqr*consqr;}

   i := 0;
   repeat
     Pos := 0;
     Wirbeln(WirbelFeld);
     for col := i to i+conSqr-1 do
       for row := i to i+conSqr-1 do
         begin
         inc(pos);
         InsertValAt(WirbelFeld[pos],col,row);
         end;
     inc(i,conSqr);
   until i = ConSide;

das ergibt ein garantiert loesbares Sudoku.Eindeutig vielleicht nicht, aber try and error setzt Du ohnehin ein.

Jetzt reduzieren und fertig ist die Kiste.
Vielleicht nochmals eine der 18432 kongruenten Anordnungen erzeugen, da Reduzieren immer in einer Ecke anfaengt und dann Zeilenweise vorgeht.

Mich wundert nur, warum Du nicht mit set's arbeitest.
i := word(FreeplaceSet); funktioniert fuer deine Case Anweisung
Optimal arbeitet Delphi mit set = [0..31] intern eben integer.
Dann fallen die bei mit vorkommenenden AND BX,$01FF weg, um mein set genau auf 9 bit zu trimmen.

Gruss Horst

Moderiert von user profile iconraziel: Code- durch Delphi-Tags ersetzt
Grishnak Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 221

Windows XP Home
Delphi 7 PE, Delphi 2005 PE
BeitragVerfasst: So 25.09.05 10:01 
@Horst_H: Sorry, aber ich blicke deinen Code nicht! Da ich mir momentan aber ebenfalls Gedanken über ein effizienteres Generieren mache, bin ich für Vorschläge offen. Könntest du deinen Algorithmus vielleicht mir Worten/Bildern beschreiben?

Eine Idee von mir ist folgende: Es wird solange eine bestimmte Anzahl (ca. 27-33) Zufallszahlen in einen leeren Sudoku geschrieben, bis dieser mindestens eine Lösung hat. Hat er mehrere Lösungen wird davon eine ausgesucht und solange Zahlen dieser Lösung eingesetzt, bis es nur noch ebendiese Lösung gibt.
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: So 25.09.05 12:11 
Hallo,

Mein Vorschlag kurz beschrieben: ;-)
Es geht einfach darum, ein fertiges Sudoku zu reduzieren.

Um moeglichst schnell, ohne irgendeinen Test (isValid etc) ein besonders zufaelliges und sofort loesbares Sudoku zu erzeugen, wende ich eben folgendes Verfahren an.
Es sind alle Ziffern von 1 bis 9 in jedem 3x3 Quadrat unterzubringen.
Ich erzeuge mit wirbeln genau eine von den 9! (1*2*3*4*5*6*7*8*9 =362880) Moeglichkeiten der Anordnung von 9 verschiedenen Ziffern
z.B.: (Hier aufsteigened bei mir nicht)
123456789,123456798,123456879,..,987654321
Diese zufaeligen Abfolgen packe ich ich dann in Quadrate die weder zeilen- noch spaltenmaessig etwas miteinander zu tun haben.(1,5,9 oder 2,4,9...)
Bsp:
127xxxxxx
543xxxxxx
968xxxxxx
xxx753xxx
xxx842xxx
xxx196xxx
xxxxxx486
xxxxxx529
xxxxxx713
mit der einer Loesung von 127787(8.38 Sekunden ohne paranoia Ausgabe(70% Kernel CPU))
127985634
543671892
968324175
896753241
315842967
274196358
732519486
681437529
459268713

Jetzt die erste Loesung davon nehmen, alle moeglicherweise folgenden interessieren jetzt nicht mehr.
Jetzt geht es ans reduzieren.

Jede zweite Ziffer auf dem Feld kann sowieso weg( Die hoechste Rekursionstiefe fuer solve war 39 bei einem komplett leeren Feld und die niedrigtse (bisher ) 19 um eien eindeutige(und keine 127787) Loesung zu haben.)
Das heisst minimal sind 19 Felder zu belegen um nach Irrungen und Wirrungen an die einzig moegliche Loesung zu kommen und maximal 39 (fast untere Dreiecksmatrix mit ein paar Luecken)

Ich stelle mir verschiedene Muster vor die man entfernt und dann erst reduziert, damit nach der Reduzierung nicht immer etwas Aehnliches herauskommt.
Alternativ betrachtest Du das FCells Feld als linear von 0..80 und entfernst nach der Methode Zufall
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
Pos := random(2);
while Pos < 81 do 
  begin
  Sudoku.Fcells[Pos Div 9,Pos mod 9]=$000;
  inc(pos,random(2)+1);
  end;
{Streicht etwa 52 Stellen)

Nach der Reduzierung bleiben meist nur 23 uebrig.
Jetzt muss die Reduzierung die Entscheidung uber schwer oder leicht treffen

Genug gefaselt, ich esse erst mal was

Gruss Horst