codice:
package sudoku_solver;
import util.Cella;
public class SudokuSolver2{
private Cella[][] sudoku;
private Cella[][] tmp;
private Cella[][][] possibiliSoluzioni;
int numeroSoluzioni;
public SudokuSolver2(Cella[][] sudoku, int numeroSoluzioni){
if(sudoku.length != 9 || sudoku[0].length != 9 || numeroSoluzioni < 1)
throw new IllegalArgumentException();
this.sudoku = sudoku;
this.numeroSoluzioni = numeroSoluzioni;
this.possibiliSoluzioni = new Cella[numeroSoluzioni][9][9];
}
public void risolvi(){
tmp = sudoku;
riempi(0,0);
}
private void riempi(int row, int col){
boolean completato = false;
/*
* primo caso di uscita
*/
if(row > 8){
completato = true;
return;
}
if(tmp [row][col].getState() == Cella.Stato.IMPOSTATO)
avanza(row, col);
else{
for(int n = 1; n< 10; n++){
/*
* se un risolvi chiama una return, si ritorna qui,
* quindi anche qui si deve controllare se il sudoku
* è stato gia completato
*/
if(!completato && assegnabile(row, col, n)){
assegna(row, col, n);
avanza(row, col);
}else{
return;
}
}
deassegna(row, col);
}
}
private void avanza(int row, int col){
if(col < 8)
riempi(row, col + 1);// vai avanti sulla stessa riga
else
riempi(row + 1, 0);// altrimenti vai a capo
}
private void assegna(int row, int col, int n){
tmp[row][col].setVal(n);
tmp[row][col].setState(Cella.Stato.ASSEGNATO);
}
private void deassegna(int row, int col){
tmp[row][col].setVal(0);
tmp[row][col].setState(Cella.Stato.NON_ASSEGNATO);
}
private boolean assegnabile(int row, int col, int n){
// controllo sulla riga
for(int i = 0; i < 9; i++)
if(sudoku[row][i].getVal() == n)
return false;
// controllo sulla colonna
for(int i = 0; i < 9; i++)
if(sudoku[i][col].getVal() == n)
return false;
//@formatter:off
//determinamento del settore da controllare
// int r, c;
// if(row < 3)
// r = 0;// si trova nella prima riga
// else if(row >= 3 && row < 6)
// r = 3;// nella seconda
// else
// r = 6;// nella terza
// if(col < 3)
// c = 0;// si trova nella prima colonna
// else if(col >= 3 && col < 6)
// c = 3;// nella seconda
// else
// c = 6;// nella terza
//@formatter:on
row = (row / 3) * 3;// migliore del codice precedente,
col = (col / 3) * 3;// molto più sintetico
// controllo del settore
for(int i = row; i < row + 3; i++)
for(int j = col; j < col + 3; j++)
if(tmp[i][j].getVal() == n)
return false;
return true;
}
public Cella[][][] getSolutions(){
return possibiliSoluzioni;
}
public static String toString(Cella[][] m){
StringBuilder sb = new StringBuilder(500);
for(int i = 0; i < 9; i++){
sb.append("| ");
for(int j = 0; j < 9; j++){
if(j == m[0].length - 1){
sb.append(m[i][j].toString());
sb.append(" |");
if(i == 2 || i == 5)
sb.append("\n------------------+-----------------+------------------\n");
else if(i != 8)
sb.append("\n| | | |\n");
}else{
sb.append(m[i][j].toString());
sb.append(" | ");
}
}
}
return sb.toString();
}
public static void main(String[] args){
int[][] a = new int[][]{
{7, 3, 9, 1, 4, 2, 0, 8, 6},
{0, 5, 1, 9, 8, 6, 3, 4, 7},
{4, 6, 8, 0, 0, 0, 0, 0, 0},
{5, 1, 6, 0, 0, 7, 2, 3, 0},
{8, 4, 7, 2, 3, 5, 6, 1, 0},
{0, 0, 3, 0, 0, 0, 7, 5, 8},
{0, 0, 0, 0, 0, 8, 4, 7, 2},
{0, 8, 0, 0, 0, 0, 0, 6, 0},
{0, 0, 0, 5, 2, 3, 8, 9, 1}};
Cella[][] s = new Cella[9][9];
for(int i = 0; i < 9; i++)
for(int j = 0; j < 9; j++){
s[i][j] = new Cella(a[i][j]);
if(a[i][j] != 0)
s[i][j].setState(Cella.Stato.IMPOSTATO);
}
// for(int i = 0; i < 9; i++)
// for(int j = 0; j < 9; j++)
// s[i][j].setVal(0);
SudokuSolver2 solver = new SudokuSolver2(s, 1);
solver.risolvi();
Cella[][][] soluzioni = solver.getSolutions();
for(int i = 0; i < soluzioni.length; i++){
System.out.println("Soluzione trovata " + (i + 1));
System.out.println(toString(soluzioni[i]));
}
}
}