seth: Sudoku

Beitrag lesen

gudn tach Mike!

grober vorschlag in pseudo-code:

Tja, danke für den Versuch, das Problem liegt im

// also: pruefe zeile, pruefe spalte, pruefe

Wie sollte ich das denn prüfen? Ich prüfe ja in meinem Script auch Zeile, Spalte und Quadrat.

mehr als das, was du bereits mit in_array tust, sollte in dieser funktion auch gar nicht geschehen

Wie soll ich da das von Dir erkannte Problem im Vorhinein vermeiden?

z.b. durch eine rekursive funktion, d.h. eine funktion, die sich selbst aufruft. auf diese weise realisiert man oft backtracking.

Für einen Deiner Blicke auf mein jüngstes Verbrechen wäre ich dankbar.

erst mal was ganz anderes:
mir faellt auf, dass du gaenzlich auf function und for verzichtest, dafuer aber z.b. (das im kontext fast schon exotisch anmutende) in_array verwendest. auch sonst ist der stil recht ungewoehnlich. dass du ein haufen copy&paste-arbeit haettest sparen koennen, durch sowas wie $s=$z; (statt s[0..9]=array(bla)) ist dir klar?
insgesamt habe ich den eindruck, als habest du bisher sehr wenig programmier-erfahrung, aber trotzdem (oder infolgedessen?) recht interessante ideen.

allerdings habe ich nicht die zeit, mir den kompletten code von vorne bis hinten anzuschauen, sondern kann dir nur tipps allgemeinerer natur geben.

dein script habe ich mal ausprobiert und nach 2 minuten abgebrochen, beim zweiten, vierten und fuenften durchlauf kamen dann jeweils vernuenftige ergebnisse nach jeweils ca. 15 sekunden heraus. beim dritten kam wieder (auch nach >1 min.) nix. der sechste durchgang lieferte nach ca. 1,5 min. ein ergebnis.
also das geht schneller. ;-)

ich empfehle dir, erstmal fuer ein paar stunden die finger von deinem programm zu lassen und erstmal handbuecher zu studieren zu den folgenden themen:
php functions (falls du des englischen nicht so maechtig bist, ersetze im url das "en" durch "de". ich empfehle allerdings eher die englische fassung),
php control structures,
wie backtracking anschaulich funktioniert, zeigt das labyrinth-bsp. imho recht gut.

spiel dann mal ein bissl mit rekursiven funktionen herum und fang dann an, auf papier dir gedanken zu machen, wie du an dein problem herangehen moechtest.
der knackpunkt ist die funktion, die ich wandere_durchs_feld genannt hatte.

ich habe sie hier mal etwas weiter ausgebaut und verwende wieder keinen richtigen php-code, sondern einen hoffentlich uebersichtlicheren pseudo-code:

  
function wandere_durchs_feld($feld, $aktuelle_zelle){  
  $geschafft=0; // rueckgabewert der funktion; wenn geschafft==1, dann ist eine loesung gefunden worden  
  if($aktuelle_zelle==81+1){  
    ausgabe($feld);  
    $geschafft=1;  
  }else{  
    if(zelle_belegbar($feld, $aktuelle_zelle)){  
      // erstelle neun eimer (fuer jede zahl einen) und initialisiere sie mit 0  
      // die eimer werden auf 1 gesetzt, wenn die jeweilige zahl nicht gewaehlt weden darf, weil sie nicht passt, oder weil sie schon mal ausprobiert wurde.  
      $bucket[1..9]=0;  
      while(!$geschafft){  
        // generiere zufallswert  
        $rnd = rand(1, 9); // erzeuge eine zufallszahl  
        // solange  
        //   der eimer der momentan ausgelosten zahl voll (==1) ist oder  
        //   der wert in der zelle nicht stehen darf, weil er sich mit den bisherigen zahlen (in zeile, spalte und subquadrat) beisst,  
        //     durchlaufe die folgende schleife  
        while($bucket[$rnd]==1 || !wert_zulaessig_in_zelle($feld, $akt_koord[0], $akt_koord[1], $rnd)){  
          $bucket[$rnd]=1; // setze den eimer der aktuell ausgelosten zahl auf 1  
          if($bucket[1..9]==1) return 0; // alle eimer voll? dann hoere auf weiterzuprobieren.  
          $rnd = rand(1, 9); // ansonsten lose eine neue zahl aus  
        }  
        $bucket[$rnd]=1; // setze den eimer der _neuen_ ausgelosten zahl auf 1  
        $feld[$aktuelle_zelle]=$rnd; // belege aktuelle zelle  
        // rekursions-/backtrackingschritt  
        $geschafft=wandere_durchs_feld($feld, $aktuelle_zelle+1);  
      }  
    }  
  }  
  return $geschafft;  
}  
// aufruf mit  
wandere_durchs_feld($feld, 0);  
// $feld ist irgendeine passende datenstruktur, z.b. bei dir z.b. $z, $c, $q.

nach der oben genannten lektuere gehe dieses beispiel mal schritt fuer schritt durch. vielleicht mal fuer den fall 4x4 (statt 9x9)

prost
seth