Click here to Skip to main content
15,892,537 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
The aim of my code, similar to the backtracking algorithm for labyrinths, is to calculate solutions for a 9 × 9 sudoku.
and The Sudoku and its solution are stored like the labyrinth in a two-dimensional int array.
I know that :The backtracking algorithm tries to enter a value of 1 ... 9 from cell [0.0] starting in a free field (value is then 0), starting with paragraph 1. Testing whether this is a valid value is a little more complicated than the maze, where it only had to be checked whether the cell is free. I think it is a good idea to use the methods
isRowOk ,
isColOk ,
isBlockOk
To take advantage of the check whether value is allowed at all, i.e. not already contained in the block.
and then These three functions must all give their OK before the backtracking algorithm tries recursively to enter a value of 1 ... 9 in the next free cell. Otherwise-if all digits 1 ... 9 have been tried-the search will be canceled (backtracking) and the next possible number will be tried in the calling search.
Do anyone have a better idea, because my code doesn't work correctly?

What I have tried:

Java
package test;

public class Sudoku {

	private final int BLOCK_SIZE = 3;

	private final int ROW_SIZE = BLOCK_SIZE * BLOCK_SIZE;

	private int nrOfSolutions, nrOfTests;

	private int[][] board;

	private int[][][] testBoard = {
			/* |---------|---------|---------| */
			{ { 5, 3, 0, 0, 7, 0, 0, 0, 0 }, { 6, 0, 0, 1, 9, 5, 0, 0, 0 }, { 0, 9, 8, 0, 0, 0, 0, 6, 0 },
					/* |---------|---------|---------| */
					{ 8, 0, 0, 0, 6, 0, 0, 0, 3 }, { 4, 0, 0, 8, 0, 3, 0, 0, 1 }, { 7, 0, 0, 0, 2, 0, 0, 0, 6 },
					/* |---------|---------|---------| */
					{ 0, 6, 0, 0, 0, 0, 2, 8, 0 }, { 0, 0, 0, 4, 1, 9, 0, 0, 5 }, { 0, 0, 0, 0, 8, 0, 0, 7, 9 } },
			/* |---------|---------|---------| */

			/* |---------|---------|---------| */
			{ { 5, 3, 4, 6, 7, 8, 9, 1, 2 }, { 6, 7, 2, 1, 9, 5, 3, 4, 8 }, { 1, 9, 8, 3, 4, 2, 5, 6, 7 },
					/* |---------|---------|---------| */
					{ 8, 5, 9, 7, 6, 1, 4, 2, 3 }, { 4, 2, 6, 8, 5, 3, 7, 9, 1 }, { 7, 1, 3, 9, 2, 4, 8, 5, 6 },
					/* |---------|---------|---------| */
					{ 9, 6, 1, 5, 3, 7, 2, 8, 4 }, { 2, 8, 7, 4, 1, 9, 6, 3, 5 }, { 3, 4, 5, 2, 8, 6, 1, 7, 0 } },
			/* |---------|---------|---------| */

			/* |---------|---------|---------| */
			{ { 0, 0, 0, 5, 4, 2, 0, 0, 0 }, { 9, 6, 7, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 3, 1, 8 },
					/* |---------|---------|---------| */
					{ 0, 0, 0, 0, 7, 0, 8, 6, 4 }, { 0, 2, 0, 6, 0, 4, 0, 9, 0 }, { 6, 4, 5, 0, 1, 0, 0, 0, 0 },
					/* |---------|---------|---------| */
					{ 8, 9, 1, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 5, 4, 7 }, { 0, 0, 0, 3, 2, 6, 0, 0, 0 } },
			/* |---------|---------|---------| */

	};

	public void testSudokuSolver() {
		for (int[][] s : this.testBoard) {
			this.board = s;
			this.print();

			nrOfSolutions = 0;
			nrOfTests = 0;
			this.solve(0, 0);
		}
	}

	private boolean isBlockOk(int row, int col, int num) {
		
		int iRowStart = (row / BLOCK_SIZE) * BLOCK_SIZE;
		int iColStart = (col / BLOCK_SIZE) * BLOCK_SIZE;

		for ( int irow = iRowStart; irow < iRowStart + BLOCK_SIZE; irow++) {
			for ( int icol = iColStart; icol < iColStart + BLOCK_SIZE; icol++) {

				if (num == board[irow][icol]) {
					return false;
				}
			}
		}
		return true;
	}

	private boolean isRowOk(int row, int num) {
		for (int i = 0; i < ROW_SIZE; i++) {
			if (num == board[row][i]) {
				return false;
			}
		}
		return true;
	}

	private boolean isColOK(int col, int num) {
		for (int i = 0; i < ROW_SIZE; i++) {
			if (num == board[i][col]) {
				return false;
			}
		}
		return true;
	}

	public void print() {
		final String horizBorder = " ┼────────┼────────┼────────┼";

		System.out.println();

		for (int i = 0; i < ROW_SIZE; i++) {
			if (0 == i % 3) {
				System.out.println(horizBorder);
			}

			for (int j = 0; j < ROW_SIZE; j++) {
				if (0 == j % 3) {
					System.out.print(" │ ");
				}

				int num = board[i][j];
				if (num == 0) {
					System.out.print("_ ");
				} else {
					System.out.print(num + " ");
				}

			}
			System.out.println(" │");
		}
		System.out.println(horizBorder);
	}

	private boolean isValid(int num, int row, int col) {
		return (isBlockOk(row, col, num) && isColOK(col, num) && isRowOk(row, num));
	}

	public boolean solve(int row, int col) {

		for (int i = 1; i < BLOCK_SIZE; i++) {
			for (int j = 1; j < BLOCK_SIZE; j++) {
				if (board[i][j] == 0) {
					for (int k = 1; k <= 9; k++) {
						board[i][j] = k;
						if (isValid(i, j, k) && solve(i, col)) {
							return true;
						}
						board[i][j] = 0;
					}
					return false;
				}
			}
		}
		return true;
	}

	public static void main(String[] args) {
		new Sudoku().testSudokuSolver();
	}

}
Posted
Updated 5-Dec-18 2:53am
v2

1 solution

Quote:
Do any have a better idea ?

the principle of backtracking works, it is just inefficient.
Human method is more efficient.
Quote:
because my code doesn't work correctly?

Then you need to debug your code !
First thing, change your code to display each board each time you set a cell and wait for user input before next step. When you see a wrong move, it means that your code do not check correctly that move, this give you hints about where to proof code.

The debugger is also of great help:
Your code do not behave the way you expect, or you don't understand why !

There is an almost universal solution: Run your code on debugger step by step, inspect variables.
The debugger is here to show you what your code is doing and your task is to compare with what it should do.
There is no magic in the debugger, it don't know what your code is supposed to do, it don't find bugs, it just help you to by showing you what is going on. When the code don't do what is expected, you are close to a bug.
To see what your code is doing: Just set a breakpoint and see your code performing, the debugger allow you to execute lines 1 by 1 and to inspect variables as it execute.
Debugger - Wikipedia, the free encyclopedia[^]

Mastering Debugging in Visual Studio 2010 - A Beginner's Guide[^]
Basic Debugging with Visual Studio 2010 - YouTube[^]
http://docs.oracle.com/javase/7/docs/technotes/tools/windows/jdb.html[^]
https://www.jetbrains.com/idea/help/debugging-your-first-java-application.html[^]
The debugger is here to only show you what your code is doing and your task is to compare with what it should do.

Have a look at:
Sudoku Solver by Andrew Stuart[^]
Simple Sudoku - freeware puzzle maker and solver[^]
Solving Sudoku[^]
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900