Zoals de titel reeds zegt is dit een klasse die in staat is eenvoudige sudoku's op te lossen (= de standaard vierkante versie).
Wie de regels van sudoku niet kent kan deze gemakkelijk terugvinden op internet, maar de basisregel is als volgt: een getal, van 1 tot 9, mag slechts 1 keer in zijn rij, kolom en vierkant (3x3) voorkomen.
Bij het meegeven van een sudoku dienen de waarden die we nog niet kennen 0 te zijn. Het script loopt door de puzzel tot alle nullen weggewerkt zijn.
Er zit een kleine main-klasse bij om het gebruik ervan aan te tonen.
package sudokusolver;
import java.util.ArrayList;
/**
* The idea of this sudokusolver is simple.
* It loops trough every zero in the puzzle and
* tries flll in every number from 1 to 9.
* There can only be one possibility - if two ore more
* numbers are possible, it just skips that value and
* jumps to the next zero. When the first loop is complete,
* at least one number should be filled in. If that isn't
* the case, it is not solvable.
* The solver will then keep looping trough the puzzle until
* all answers are found. If it loops once trough the puzzle
* without filling in at least one number, it's also unsolvable.
*
* @author Maarten Ureel
* @version 1.0
*/
public class SimpleSudokuSolver {
public static int[][] solve(int[][] sudoku) throws UnsolvableSudokuException {
boolean solvedSomething = false;
// As long as there is a zero present, keep trying
while (!solved(sudoku)) {
for (int row = 0; row < sudoku.length; row++) {
// Loop trough all rows
for (int col = 0; col < sudoku[row].length; col++) {
// Loop trough the columns in the row
if (sudoku[row][col] == 0) {
ArrayList<Integer> possibilities = new ArrayList<Integer>();
// Loop trough all possibilitis, eliminate those
// that aren't possible
for (int i = 1; i <= 9; i++) {
// Check 1: see if the number is already in this row
if (!getRow(sudoku, row).contains(i) &&
!getColumn(sudoku, col).contains(i) &&
!getSquare(sudoku, row, col).contains(i)) {
possibilities.add(i);
}
}
if (possibilities.size() == 1) {
// There is only one possibility - so it's a good one :)
sudoku[row][col] = possibilities.get(0);
solvedSomething = true;
}
}
}
}
if(!solvedSomething) {
throw new UnsolvableSudokuException();
}
solvedSomething = false;
}
return sudoku;
}
public static void print(int[][] sudoku) {
for (int row = 0; row < sudoku.length; row++) {
// Divide in blocks
if (row % 3 == 0 && row != 0) {
System.out.println();
}
for (int col = 0; col < sudoku[row].length; col++) {
// Divide in blocks
if (col % 3 == 0 && col != 0) {
System.out.print(" ");
}
System.out.print(sudoku[col][row] + " ");
}
System.out.println();
}
}
private static boolean solved(int[][] sudoku) {
for (int row = 0; row < sudoku.length; row++) {
// Loop trough all rows
for (int col = 0; col < sudoku[row].length; col++) {
// Loop trough the columns in the row
if (sudoku[row][col] == 0) {
// Not yet solved - stop finding out
return false;
}
}
}
// There was no false returned (zero present), so it's solved!
return true;
}
private static ArrayList<Integer> getRow(int[][] sudoku, int rowNumber) {
ArrayList<Integer> row = new ArrayList<Integer>();
for (int i = 0; i < sudoku[rowNumber].length; i++) {
row.add(sudoku[rowNumber][i]);
}
return row;
}
private static ArrayList<Integer> getColumn(int[][] sudoku, int columnNumber) {
ArrayList<Integer> col = new ArrayList<Integer>();
// Loop trough all rows and add the number in the given column
for (int row = 0; row < sudoku.length; row++) {
col.add(sudoku[row][columnNumber]);
}
return col;
}
private static ArrayList<Integer> getSquare(int[][] sudoku, int rowNumber, int columnNumber) {
ArrayList<Integer> square = new ArrayList<Integer>();
// Define the upperleft corner of the square
rowNumber = (int) Math.floor(rowNumber / 3) * 3;
columnNumber = (int) Math.floor(columnNumber / 3) * 3;
int rowMax = rowNumber + 3;
int colMax = columnNumber + 3;
// Fill
for (int row = rowNumber; row < rowMax; row++) {
for (int col = columnNumber; col < colMax; col++) {
square.add(sudoku[row][col]);
}
}
return square;
}
}
packagesudokusolver;
importjava.util.ArrayList;
/**
* The idea of this sudokusolver is simple.
* It loops trough every zero in the puzzle and
* tries flll in every number from 1 to 9.
* There can only be one possibility - if two ore more
* numbers are possible, it just skips that value and
* jumps to the next zero. When the first loop is complete,
* at least one number should be filled in. If that isn't
* the case, it is not solvable.
* The solver will then keep looping trough the puzzle until
* all answers are found. If it loops once trough the puzzle
* without filling in at least one number, it's also unsolvable.
package sudokusolver;
/**
*
* @author Maarten Ureel
*/
class UnsolvableSudokuException extends Exception {
public UnsolvableSudokuException() {
super("The given sudoku is not solvable by this solver...");
}
}