Seite 1 von 1

sudoku löser brauche hilfe

Verfasst: Do Jan 14, 2010 5:35 pm
von SolidS
hallo hab als aufgabe ein sudoku zu lösen habs so weit auch hin bekommen nur hab ich das zu lösende sudoku direkt mit integriert und jetzt würde ich doch gerne es selber eingeben oder noch besser aus einer .txt einlesen lassen könnte mir da vllt einer weiter helfen?
hier mal mein bisheriger code achso das ganze ist mit C geschrieben

Code: Alles auswählen

 #include <stdio.h>

int feld[9][9] = { /* Das zu loesende Sudoku */
{0,3,0, 0,0,0, 9,0,2},
{0,0,0, 1,9,5, 0,0,0},
{0,9,8, 0,0,0, 0,6,0},

{8,0,0, 0,6,0, 0,0,0},
{4,0,0, 0,0,3, 0,0,1},
{0,0,3, 0,2,0, 0,5,0},

{0,6,0, 0,0,0, 2,8,0},
{0,0,0, 4,1,9, 0,0,5},
{3,0,0, 2,0,0, 0,7,0},
};
void output() {
int i,j;
for ( i = 0; i < 9; i++ )
{
for ( j = 0; j < 9; j++ ) {
printf("%d|",feld[i][j]);
if ( j % 3 == 2) printf(" ");
}
printf("\n");
if ( i % 3 == 2 ) printf("\n");
}
printf("--------------------\n\n");
}

/* Es wird u>0 vorausgesetzt. Rueckgabe von 1, falls u bei Position
(a,b) moeglich, sonst Rueckgabe von 0. */
int check(int a, int b, int u) {
int i,j;
if ( feld[a][b]) return 0;
for (i = 0; i < 9; i++) {
if (u == feld[a][i]) return 0;
if (u == feld[i][b]) return 0;
}
for ( i = a - a%3 ; i < a - a%3 + 3; i++)
for (j = b - b%3 ; j < b - b%3 + 3; j++)
if (u == feld[i][j])
return 0;
return 1;
}

int versuche(int k) { /* k --> k/9 k%9 */
int i, q;
while ( k<=80 && feld[k/9][k%9] ) k++; /* naechstes freies Feld? */
if ( k == 81 ) return 1; /* alles belegt, fertig */
for ( q=0, i=1 ; q == 0 && i <= 9 ; i++) {
if ( check(k/9, k%9, i) ) { /* teste das Feld k mit allen i */
feld[k/9][k%9] = i;
if (k == 80) q = 1; /* falls letztes Feld, Erfolg: q=1 */
else
if ( (q = versuche(k+1) ) == 0) /* sonst naechstes Feld */
feld[k/9][k%9] = 0; /* Falls erfolglos, Ruecksetzen */
}
}
return q;
}

int main() {
output();
versuche(0);
output();
}

Re: sudoku löser brauche hilfe

Verfasst: Do Jan 14, 2010 6:35 pm
von Bebu
Dazu musst du dich mit dem Thema Streams auseinandersetzen. Ich glaube dazu haben wir noch nichts im Wiki, aber du kannst dir mal das hier durchsehen: http://de.wikibooks.org/wiki/C-Programmierung:_Dateien

Im Grunde funktioniert die Sache ähnlich, wie Daten Ein- und Ausgabe von der Konsole, nur die Quelle ändert sich.

Re: sudoku löser brauche hilfe

Verfasst: Do Jan 14, 2010 7:29 pm
von Xin
Ich würde ein CSV File daraus machen. Die kann man sehr leicht parsen und dafür dann einen Parser schreiben. Die sind sehr leicht zu lesen.

Re: sudoku löser brauche hilfe

Verfasst: Do Jan 14, 2010 8:13 pm
von cloidnerux
Ist doch im Grunde einfach.
Man gibt als regel in der txt Datei an, das die Nummern jeweils mit folgendem Leerzeichen und enter am Ende der Zeile angegben werden, offene Felder kannst du durch ein Belibiges zeichen darstellen:

Code: Alles auswählen

o 5 4 2 o 3 9 3 o [enter]
1 o 8 o 4 3 o o o [enter]
...
Du liest jezt den die Datei Zeilenweise oder Blockweise(18Byte) ein, und weist dann genau, das an jeder 2 Stelle von 0 aus eine zahl oder "o" stehen wird, und das musst du dann nurnoch von char zu einem int parsen.

Re: sudoku löser brauche hilfe

Verfasst: Do Jan 14, 2010 8:36 pm
von SolidS
habs jetzt mal was umgemodelt aber bekomme da nen blöden fehler
|23|error: invalid conversion from `const char*' to `char'|

Code: Alles auswählen

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int checker(int[][9],int,int);
int writer(int[][9],int,int);

int main(int argc, char *argv[]){
	int k1 = 0, k2 = 0;
	printf("Willkommen im Sodoku-loesungs Programm!\n");
	char sodoku[30]="sodoku.txt";
	FILE *textdatei;
	textdatei = fopen(sodoku,"r");
	if(textdatei!=NULL){
		int gitter[9][9];
		int i, j, k = 0, l = 0;
		char buffer[50];
		char buffer2[50];
		for(i = 0; i < 9; i++){
			fgets(buffer,50,textdatei);
			for(j = 0;j < 9; j++){
				buffer2[0]=buffer[j];
23 fehler----->		buffer2[1]="\0";
				gitter[i][j]=atoi(buffer2);
			}
		}
		writer(gitter,0,0);
	}
	fclose(textdatei);
	system("PAUSE");
	return 0;
}

int checker(int gitter[][9],int i,int j){
	int a, z, w, b = 0, c = 0,wert;
	wert = gitter[i][j];
	for(a = 0; a < 9; a++){
		if(gitter[i][a] == wert){
			b++;
		}
	}
	if(b > 1){
		return 1;
	}
	b = 0;
	for(a = 0; a < 9; a++){
		if(gitter[a][j] == wert){
			b++;
		}
	}
	if(b > 1){
		return 1;
	}

	int m1 = 0,m2 = 0;
	if(i < 3){
		m1 = 1;
	}

    else if(i < 6){
		m1 = 4;
	}
    else if(i < 9){
		m1 = 7;
	}
	if(j < 3){
		m2 = 1;
	}
    else if(j < 6){
           m2 = 4;
    }
    else if(j < 9){
           m2 = 7;
    }
    for(a= m1 - 1;a <= m1 + 1; a++){
        for(b = m2 - 1;b <= m2 +1; b++){
           if(gitter[a][b] == wert){
              c++;
		   }
		}
	}
	if(c > 1){
		return 1;
	}
	return 0;
}

int writer(int gitter[][9], int i, int j){
	int neui = 0, neuj = 0, v, w, z;
	if(i<8){
		neui= i +1;
		neuj = j;
	}
	else{
		neui = 0;
		neuj = j + 1;
	}
	if(gitter[i][j]!= 0){
		writer(gitter,neui,neuj);
	}
	else{
		for(v = 1; v < 10; v++){
			gitter[i][j] = v;
			if(checker(gitter,i,j) == 0){
				if(i == 8 && j == 8){
					for(w = 0; w < 9; w++){
						for(z = 0; z < 9; z++){
							printf("%d,",gitter[w][z]);
						}
						printf("\n");
					}
				}
				else{
					writer(gitter,neui,neuj);
					gitter[i][j] = 0;
				}
			}
			gitter[i][j] = 0;
		}
	}
}


Re: sudoku löser brauche hilfe

Verfasst: Do Jan 14, 2010 10:16 pm
von Xin
SolidS hat geschrieben:habs jetzt mal was umgemodelt aber bekomme da nen blöden fehler
|23|error: invalid conversion from `const char*' to `char'|

Code: Alles auswählen

23 fehler----->		buffer2[1]="\0";
"\0" ist ein String (char const *), der ein Nullbyte enthält. Buffer2[1] ist ein Buchstabe (char). Wenn Du das Nullbyte als Nullbyte schreiben möchtest und nicht als String mit Nullbyte, dann musst Du einzelne Hochkommas nehmen: '\0’.

Re: sudoku löser brauche hilfe

Verfasst: Do Jan 14, 2010 10:20 pm
von Dirty Oerti
cloidnerux hat geschrieben:Ist doch im Grunde einfach.
Man gibt als regel in der txt Datei an, das die Nummern jeweils mit folgendem Leerzeichen und enter am Ende der Zeile angegben werden, offene Felder kannst du durch ein Belibiges zeichen darstellen:

Code: Alles auswählen

o 5 4 2 o 3 9 3 o [enter]
1 o 8 o 4 3 o o o [enter]
...
Du liest jezt den die Datei Zeilenweise oder Blockweise(18Byte) ein, und weist dann genau, das an jeder 2 Stelle von 0 aus eine zahl oder "o" stehen wird, und das musst du dann nurnoch von char zu einem int parsen.
Und um den Speicheraufwand zu reduzieren kannst du die Leerzeichen zwischen den Daten auch weglassen...
Dass funktioniert natürlich nur, wenn du weißt, dass in einem "Datenfeld" immer nur eine Ziffer steht. Ist in dem Fall ja aber kein Problem.

Re: sudoku löser brauche hilfe

Verfasst: Do Jan 14, 2010 10:28 pm
von SolidS
ahhh vielen dank jetzt leuft es sollte mehr auf die kleinigkeiten achten ;-)