SudokuSolver
Auteur: Maarten - 20 februari 2009 - 13:41 - Gekeurd door: Koen - Hits: 2449 - Aantal punten: 1.63 (4 stemmen)
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.
|
Code: |
SimpleSudokuSolver.java
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;
}
}
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) { } for (int col = 0; col < sudoku[row].length; col++) { // Divide in blocks if (col % 3 == 0 && col != 0) { } System. out. print(sudoku [col ][row ] + " "); } } } 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; } }
UnsolvableSudokuException.java
package sudokusolver;
/**
*
* @author Maarten Ureel
*/
class UnsolvableSudokuException extends Exception {
public UnsolvableSudokuException() {
super("The given sudoku is not solvable by this solver...");
}
}
package sudokusolver; /** * * @author Maarten Ureel */ class UnsolvableSudokuException extends Exception { public UnsolvableSudokuException() { super("The given sudoku is not solvable by this solver..."); } }
Main.java
package sudokusolver;
/**
*
* @author Maarten Ureel
*/
public class Main {
public static void main(String[] args) {
int row1[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
int row2[] = {3, 6, 7, 8, 0, 1, 0, 2, 0};
int row3[] = {9, 0, 2, 0, 0, 5, 3, 0, 1};
int row4[] = {5, 0, 0, 0, 9, 0, 0, 0, 8};
int row5[] = {0, 0, 0, 7, 0, 4, 0, 0, 0};
int row6[] = {4, 0, 0, 0, 5, 0, 0, 0, 2};
int row7[] = {0, 0, 5, 1, 0, 0, 9, 0, 4};
int row8[] = {0, 9, 0, 4, 0, 2, 7, 1, 5};
int row9[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
int[] sudoku[] = {row1, row2, row3, row4, row5, row6, row7, row8, row9};
System.out.println("Before: ");
SimpleSudokuSolver.print(sudoku);
sudoku = SimpleSudokuSolver.solve(sudoku);
System.out.println("After: ");
SimpleSudokuSolver.print(sudoku);
}
}
package sudokusolver; /** * * @author Maarten Ureel */ public class Main { public static void main (String[] args ) { int row1[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; int row2[] = {3, 6, 7, 8, 0, 1, 0, 2, 0}; int row3[] = {9, 0, 2, 0, 0, 5, 3, 0, 1}; int row4[] = {5, 0, 0, 0, 9, 0, 0, 0, 8}; int row5[] = {0, 0, 0, 7, 0, 4, 0, 0, 0}; int row6[] = {4, 0, 0, 0, 5, 0, 0, 0, 2}; int row7[] = {0, 0, 5, 1, 0, 0, 9, 0, 4}; int row8[] = {0, 9, 0, 4, 0, 2, 7, 1, 5}; int row9[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; int[] sudoku[] = {row1, row2, row3, row4, row5, row6, row7, row8, row9}; System. out. println("Before: "); SimpleSudokuSolver.print(sudoku); sudoku = SimpleSudokuSolver.solve(sudoku); System. out. println("After: "); SimpleSudokuSolver.print(sudoku); } }
Download code (.txt)
|
|
Stemmen |
Niet ingelogd. |
|