Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
/*
Risolutore di Sudoku, versione 1.1
Autore: Francesco Bottacin
Data: Maggio 2009
Descrizione: risolve un Sudoku classico 9 x 9
Puo' trovare tutte le soluzioni possibili e scriverle in un file.
Dopo aver trovato una soluzione viene chiesto se si vuole continuare a cercarne altre.
Uso: sudoku [-o outfile] [-t outfile] filedati
il filedati e' un file di testo che contiene i dati iniziali nel seguente
formato:
dove val_h e' il numero da inserire nella casella di posto (i_h, j_h)
[ i_h = numero di riga, con 1 <= i_h <= 9;
j_h = numero di colonna, con 1 <= j_h <= 9;
val_h e' intero, con 1 <= val_h <= 9.
Naturalmente non si possono inserire piu' di 81 valori ]
L'opzione -o outfile scrive le soluzioni trovate nel file outfile.
L'opzione -t outfile scrive le soluzioni nel file outfile in Plain TeX
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct {
int num;
int p;
int v[9];
} a[9][9];
struct {
int i;
int j;
} stack[81];
int livelloAttuale = 0;
int numZeri = 81;
int iMin;
int jMin;
http://www.math.unipd.it/~bottacin/progs/sudoku.c 2/7
3/11/2016 www.math.unipd.it/~bottacin/progs/sudoku.c
}
if ( a[i-1][j-1].num != 0 ) {
fclose( fp );
panic("si e' cercato di inserire un valore due volte nello stesso posto");
}
a[i-1][j-1].num = n;
numZeri--;
}
fclose( fp );
}
http://www.math.unipd.it/~bottacin/progs/sudoku.c 3/7
3/11/2016 www.math.unipd.it/~bottacin/progs/sudoku.c
else
return 1;
}
http://www.math.unipd.it/~bottacin/progs/sudoku.c 4/7
3/11/2016 www.math.unipd.it/~bottacin/progs/sudoku.c
exit(0);
}
if ( outSuFile == 1 ) {
// controllo che il file di output e il file di dati non abbiano lo stesso nome
if ( strcmp( argv[0], argv[1] ) == 0 )
panic("Il file di output ha lo stesso nome del file dei dati");
printf("Le soluzioni verranno scritte nel file %s\n", *argv);
if ( (outFp = fopen(*argv,"r")) == NULL ) { // il file non esiste, OK
if ( (outFp = fopen(*argv,"w")) == NULL ) { // non riesco a creare il file
panic("Non riesco a creare il file di output");
}
} else { // il file esiste gia', KO
fclose(outFp);
panic("Il file di output esiste gia', scegliere un nome diverso.");
}
argv++;
}
init();
leggiFile( *argv );
printf("Il Sudoku proposto e':\n\n");
stampaMatrice();
printf("\n");
if ( outSuFile && !texOut ) {
if ( outFp == NULL )
panic("Errore interno: questo non dovrebbe succedere!");
fprintf(outFp, "Il Sudoku proposto e':\n\n");
stampaMatriceSuFile( outFp );
fprintf(outFp, "\n");
}
if ( outSuFile && texOut ) {
if ( outFp == NULL )
panic("Errore interno: questo non dovrebbe succedere!");
fprintf(outFp, "%s", "%Plain TeX\n\\parindent=0pt\n\n");
fprintf(outFp, "Il Sudoku proposto \\`e:\n\n");
fprintf(outFp, "\\bigskip\n\n");
stampaMatriceSuTeXFile( outFp );
fprintf(outFp, "\\bigskip\n\n");
}
if ( datiNonAccettabili() ) {
printf("Il Sudoku proposto non e' coerente con le regole del gioco.\n");
printf("Controllare i dati introdotti (altrimenti la soluzione non esiste)\n");
if ( outSuFile && !texOut ) {
if ( outFp == NULL )
panic("Errore interno: questo non dovrebbe succedere!");
fprintf(outFp, "Il Sudoku proposto non e' coerente con le regole del gioco.\n");
fprintf(outFp, "Controllare i dati introdotti (altrimenti la soluzione non
esiste)\n");
fclose(outFp);
}
if ( outSuFile && texOut ) {
if ( outFp == NULL )
panic("Errore interno: questo non dovrebbe succedere!");
fprintf(outFp, "\n\\bigskip\n\n");
fprintf(outFp, "Il Sudoku proposto non \\`e coerente con le regole del
gioco.\n");
fprintf(outFp, "Controllare i dati introdotti (altrimenti la soluzione non
esiste)\n");
fprintf(outFp, "\n\\bye\n");
fclose(outFp);
}
return 0;
}
while ( continua ) {
while ( settaPossibilita() == 0 ) {
if ( provaAltraStrada() == 0 ) {
http://www.math.unipd.it/~bottacin/progs/sudoku.c 5/7
3/11/2016 www.math.unipd.it/~bottacin/progs/sudoku.c
if ( numSol == 0 ) {
printf("Questo Sudoku non ha soluzione\n");
if ( outSuFile && !texOut ) {
if ( outFp == NULL )
panic("Errore interno: questo non dovrebbe succedere!");
fprintf(outFp, "Questo Sudoku non ha soluzione\n");
}
if ( outSuFile && texOut ) {
if ( outFp == NULL )
panic("Errore interno: questo non dovrebbe succedere!");
fprintf(outFp, "\n\\bigskip\n\n");
fprintf(outFp, "Questo Sudoku non ha soluzione\n");
}
}
else {
printf("Non ci sono altre soluzioni\n");
if ( outSuFile && !texOut ) {
if ( outFp == NULL )
panic("Errore interno: questo non dovrebbe succedere!");
fprintf(outFp, "Non ci sono altre soluzioni\n\n");
}
if ( outSuFile && texOut ) {
if ( outFp == NULL )
panic("Errore interno: questo non dovrebbe succedere!");
fprintf(outFp, "\n\\bigskip\n\n");
fprintf(outFp, "Non ci sono altre soluzioni\n\n");
}
}
printf("(Numero di tentativi = %d)\n\n", numTentativi);
if ( outSuFile && !texOut ) {
if ( outFp == NULL )
panic("Errore interno: questo non dovrebbe succedere!");
fprintf(outFp, "(Numero di tentativi = %d)\n\n", numTentativi);
fclose(outFp);
}
if ( outSuFile && texOut ) { // da sistemare
if ( outFp == NULL )
panic("Errore interno: questo non dovrebbe succedere!");
fprintf(outFp, "(Numero di tentativi = %d)\n\n", numTentativi);
fprintf(outFp, "\n\\bye\n");
fclose(outFp);
}
return 0;
}
numTentativi++;
}
assegnaValore( iMin, jMin );
if ( numZeri == 0 ) { // ho trovato una soluzione
numSol++;
printf("Soluzione n. %d\n\n", numSol);
stampaMatrice();
printf("\n");
printf("(Numero di tentativi = %d)\n\n", numTentativi);
if ( outSuFile && !texOut ) {
if ( outFp == NULL )
panic("Errore interno: questo non dovrebbe succedere!");
fprintf(outFp, "Soluzione n. %d\n\n", numSol);
stampaMatriceSuFile( outFp );
fprintf(outFp, "\n");
fprintf(outFp, "(Numero di tentativi = %d)\n\n", numTentativi);
}
if ( outSuFile && texOut ) {
if ( outFp == NULL )
panic("Errore interno: questo non dovrebbe succedere!");
fprintf(outFp, "Soluzione n.~%d\n\n", numSol);
fprintf(outFp, "\\bigskip\n\n", numSol);
stampaMatriceSuTeXFile( outFp );
fprintf(outFp, "\n(Numero di tentativi = %d)\n\n", numTentativi);
fprintf(outFp, "\\bigskip\n\n");
http://www.math.unipd.it/~bottacin/progs/sudoku.c 6/7
3/11/2016 www.math.unipd.it/~bottacin/progs/sudoku.c
}
if ( trovaTutteSol == 0 ) {
printf("Continuare? [S = si', N = no, T = trova tutte le soluzioni senza
chiedere]: ");
ch = getchar();
while ( getchar() != '\n' ) {}; // salta tutti gli altri caratteri
printf("\n");
switch ( ch ) {
case 's':
case 'S':
continua = 1;
break;
case 'n':
case 'N':
continua = 0;
printf("Ricerca interrotta\n");
if ( outSuFile && !texOut ) {
if ( outFp == NULL )
panic("Errore interno: questo non dovrebbe succedere!");
fprintf(outFp, "Ricerca interrotta\n");
}
if ( outSuFile && texOut ) {
if ( outFp == NULL )
panic("Errore interno: questo non dovrebbe succedere!");
fprintf(outFp, "\n\\bigskip\n\n");
fprintf(outFp, "Ricerca interrotta\n");
}
break;
case 't':
case 'T':
continua = 1;
trovaTutteSol = 1;
break;
default:
continua = 0;
printf("Carattere non valido\n");
break;
}
}
}
}
if ( outSuFile ) {
if ( outFp == NULL )
panic("Errore interno: questo non dovrebbe succedere!");
if ( texOut )
fprintf(outFp, "\n\\bye\n");
fclose(outFp);
}
return 0;
}
http://www.math.unipd.it/~bottacin/progs/sudoku.c 7/7