Ho scritto un codice che risolva uno dato schema di sudoku ma il programma  gira sempre senza dare soluzione e senza andare in crash perchè ha disponibilità di memoria .
Non so in che modo controllare la solve che è la funzione principale. La solve è basata  su inserimenti consecutivi di valori  in ogni cella libera che soddisfano le regole del sudoku e quindi è uno schema risolutivo “poco intelligente”e sicuramente molto oneroso per il sistema.
il codice  è incompleto perchè manca la funzione per poter inserire  uno schema di sudoku da file ma è un aspetto secondario  perchè  ho fissatoo a priori una configurazione iniziale della matrice.
 

#include <stdio.h>
#include <stdbool.h>
int m[9][9]= { {4,0,0,0,0,0,0,0,0}, 
               {0,8,3,5,0,0,4,1,0},
               {0,7,0,6,0,0,0,2,0} ,
               {0,0,0,0,8,0,1,6,0},
               {0,0,0,2,0,6,0,0,0} ,
               {0,1,7,0,4,0,0,0,0},
               {0,5,0,0,0,9,0,4,0} ,
               {0,4,2,0,0,1,7,3,0} ,
               {0,0,0,0,0,0,0,0,0}};
 // visualizza griglia sudoku
void visualizza( void)
{
	for (int i=0; i<9; i++) {
		for (int j=0; j<9; j++)
			printf("%3d",m[i][j]);
		printf("n");
	}
	printf("n");
	return;
}
//restituisce true se la configuarazione della griglia è valida
bool presente_riga( int x, int riga)
{
	for (int i=0; i<9; i++){
		if( m[riga][i]== x)
			return true;
	}
	return false;
}
bool presente_colonna ( int x, int colonna )
{
	for (int i=0; i<9; i++){
		if ( m[i][colonna]==x )
			return true;
	}
	return false;
}
bool presente_quadrante (int x, int riga, int colonna )
{
	for (int i=0; i<3; i++)
		for (int j=0; j<3; j++) {
			int s = (riga/3)*3 + i;
			int t = (colonna/3)*3 + j;
			if ( m[s][t] == x)
				return true;
	}
	return false;
}
bool config_valida (int x, int riga, int colonna)
{
	if ( !presente_riga (x,riga) && !presente_colonna (x, colonna) && !presente_quadrante(x, riga, colonna))
		return true;
	return false;
}
//restituisce vero se ha risolto il sudoku
bool solve( void )
{
	int inserimenti = 0;
	bool libero = false; 	// variabile per sapere se esiste una cella libera
	int r =-1; int c=-1; 	// indici riga e colonna  libere
	//cerca r e c primi indici tali che  m[r,c]=0
	do {
		r++;
		c=-1;
		do {
			c++;
			if (m[r][c]==0) libero=true;
		} while (libero==false && c<8);
	} while (libero==false && r<9);
	//printf("ncella libera %d , %dn", r+1, c+1);
	//se è stata trovata una cella vuota inserisci un valore e richiama funzione se la config è valida
	if ( libero ) {
		for ( int x=1; x<=9; x++ ) { 	//prova a inserire nella cella ogni valore possibile poi controlla
			if ( config_valida ( x , r, c ) ) {
				m[r][c] = x ;				// se la config è valida inserisci l'elemento
				inserimenti++;   //printf("n inserito %d in %d, %dnn", x, r+1, c+1); visualizza();
				if (solve()) return true;  //se la chiamata ricorsiva torna true, torna true alla main
				else {
					m[r][c] = 0; //se l'inserimento fatto non porta alla soluzione riporta la cella a 0
					inserimenti--;   //printf("n cancellato %d in %d, %dnn", x, r+1, c+1);   visualizza ();
				}
			}	//se la config non è valida prova con il prox x
		}
		if ( inserimenti == 0) return false;	//se non è stato possibile inserire alcun valore in una cella libera c'è un errore
	}
	else return true;   //non ci sono più celle vuote -> finito! questa è l'ultima chiamata di solve
}
int main()
{
	//configurazione();
	printf("nschema inizialen");
	visualizza();
	if ( solve() ) {
		printf("nsudoku risolto!n");
		visualizza();
	}	else printf("nil sudoku non ammette soluzione");
	return 0;
}

 

2 Replies to “Sudoku”

  1. Ho provato a compilare e testare il programma, con la matrice data sul mio pc mi compila correttamente e non cicla, ma termina dicendo che lo schema non ha soluzione. Se lo schema che hai inserito come suppongo invece l’ammette, allora devi controllare attentamente lo schema della ricorsione. Prova a eseguire a mano lo schema carta e penna e verificare. Inoltre: qual’è il caso base della ricorsione (quando sei sicuro che la chiamata ricorsiva termini?). Sei sicura che la funzione config_valida sia giusta? E a che serve esattamente?, scrivi dei commenti con dei predicati (asserzioni) come pre-condizioni e post-condizioni per ogni funzione che scrivi, e indica chiaramente lo scopo della funzione. Controlla se l’albero della ricorsione che viene generato dal tuo programma è in accordo con l’ordine con cui dovresti trovare la soluzione (per l’istanza inserita nella matrice).

  2. Risolto e funziona!!!
    alla riga 81 bisogna imporre che il while cicli con r<8 e non r<9 perchè in questo modo la riga viene incrementata fino a 9 e non fino a 10.
    ora mi occupo di sistemare i commenti, migliorare la scrittura del programma e creare la funzione per l'inserimento da input o file.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *