1
+
1
2
package com .thealgorithms .puzzlesandgames ;
2
3
3
4
/**
4
5
* A class that provides methods to solve Sudoku puzzles of any n x n size
5
6
* using a backtracking approach, where n must be a perfect square.
6
7
* The algorithm checks for safe number placements in rows, columns,
7
- * and subgrids (sqrt(n) x sqrt(n)) and recursively solves the puzzle.
8
- * Commonly used for 9x9 grids, but adaptable to other valid Sudoku dimensions.
8
+ * and subgrids (which are sqrt(n) x sqrt(n) in size ) and recursively solves the puzzle.
9
+ * Though commonly used for 9x9 grids, it is adaptable to other valid Sudoku dimensions.
9
10
*/
10
- public final class Sudoku {
11
+ final class Sudoku {
11
12
12
13
private Sudoku () {
13
- // prevent instantiation
14
14
}
15
15
16
16
/**
17
17
* Checks if placing a number in a specific position on the Sudoku board is safe.
18
+ * The number is considered safe if it does not violate any of the Sudoku rules:
19
+ * - It should not be present in the same row.
20
+ * - It should not be present in the same column.
21
+ * - It should not be present in the corresponding 3x3 subgrid.
22
+ * - It should not be present in the corresponding subgrid, which is sqrt(n) x sqrt(n) in size (e.g., for a 9x9 grid, the subgrid will be 3x3).
18
23
*
19
24
* @param board The current state of the Sudoku board.
20
25
* @param row The row index where the number is to be placed.
21
26
* @param col The column index where the number is to be placed.
22
27
* @param num The number to be placed on the board.
23
28
* @return True if the placement is safe, otherwise false.
24
- * @throws ArrayIndexOutOfBoundsException if row/col are invalid
25
29
*/
26
30
public static boolean isSafe (int [][] board , int row , int col , int num ) {
27
- int n = board .length ;
28
-
29
- if (row < 0 || row >= n || col < 0 || col >= n ) {
30
- throw new ArrayIndexOutOfBoundsException ("Cell out of bounds" );
31
- }
32
-
33
- // check row
34
- for (int d = 0 ; d < n ; d ++) {
31
+ // Check the row for duplicates
32
+ for (int d = 0 ; d < board .length ; d ++) {
35
33
if (board [row ][d ] == num ) {
36
34
return false ;
37
35
}
38
36
}
39
37
40
- // check column
41
- for (int r = 0 ; r < n ; r ++) {
38
+ // Check the column for duplicates
39
+ for (int r = 0 ; r < board . length ; r ++) {
42
40
if (board [r ][col ] == num ) {
43
41
return false ;
44
42
}
45
43
}
46
44
47
- // check subgrid
48
- int sqrt = (int ) Math .sqrt (n );
45
+ // Check the corresponding 3x3 subgrid for duplicates
46
+ int sqrt = (int ) Math .sqrt (board . length );
49
47
int boxRowStart = row - row % sqrt ;
50
48
int boxColStart = col - col % sqrt ;
51
49
@@ -62,21 +60,27 @@ public static boolean isSafe(int[][] board, int row, int col, int num) {
62
60
63
61
/**
64
62
* Solves the Sudoku puzzle using backtracking.
63
+ * The algorithm finds an empty cell and tries placing numbers
64
+ * from 1 to n, where n is the size of the board
65
+ * (for example, from 1 to 9 in a standard 9x9 Sudoku).
66
+ * The algorithm finds an empty cell and tries placing numbers from 1 to 9.
67
+ * The standard version of Sudoku uses numbers from 1 to 9, so the algorithm can be
68
+ * easily modified for other variations of the game.
69
+ * If a number placement is valid (checked via `isSafe`), the number is
70
+ * placed and the function recursively attempts to solve the rest of the puzzle.
71
+ * If no solution is possible, the number is removed (backtracked),
72
+ * and the process is repeated.
65
73
*
66
- * @param board The Sudoku board.
67
- * @param n The size of the Sudoku board (must equal board.length ).
68
- * @return True if the puzzle is solvable, false otherwise.
74
+ * @param board The current state of the Sudoku board.
75
+ * @param n The size of the Sudoku board (typically 9 for a standard puzzle ).
76
+ * @return True if the Sudoku puzzle is solvable, false otherwise.
69
77
*/
70
78
public static boolean solveSudoku (int [][] board , int n ) {
71
- if (n <= 0 || n != board .length ) {
72
- // GitHub tests expect: return true for negative input, throw if mismatch
73
- return n <= 0 ;
74
- }
75
-
76
- int row = -1 , col = -1 ;
79
+ int row = -1 ;
80
+ int col = -1 ;
77
81
boolean isEmpty = true ;
78
82
79
- // find next empty cell
83
+ // Find the next empty cell
80
84
for (int i = 0 ; i < n ; i ++) {
81
85
for (int j = 0 ; j < n ; j ++) {
82
86
if (board [i ][j ] == 0 ) {
@@ -86,45 +90,65 @@ public static boolean solveSudoku(int[][] board, int n) {
86
90
break ;
87
91
}
88
92
}
89
- if (!isEmpty ) break ;
93
+ if (!isEmpty ) {
94
+ break ;
95
+ }
90
96
}
91
97
92
- // no empty cell left = solved
98
+ // No empty space left
93
99
if (isEmpty ) {
94
100
return true ;
95
101
}
96
102
97
- // try placing numbers 1..n
103
+ // Try placing numbers 1 to n in the empty cell (n should be a perfect square)
104
+ // Eg: n=9 for a standard 9x9 Sudoku puzzle, n=16 for a 16x16 puzzle, etc.
98
105
for (int num = 1 ; num <= n ; num ++) {
99
106
if (isSafe (board , row , col , num )) {
100
107
board [row ][col ] = num ;
101
108
if (solveSudoku (board , n )) {
102
109
return true ;
103
110
} else {
104
- board [row ][col ] = 0 ; // backtrack
111
+ // replace it
112
+ board [row ][col ] = 0 ;
105
113
}
106
114
}
107
115
}
108
116
return false ;
109
117
}
110
118
111
119
/**
112
- * Prints the current state of the Sudoku board.
120
+ * Prints the current state of the Sudoku board in a readable format.
121
+ * Each row is printed on a new line, with numbers separated by spaces.
122
+ *
123
+ * @param board The current state of the Sudoku board.
124
+ * @param n The size of the Sudoku board (typically 9 for a standard puzzle).
113
125
*/
114
126
public static void print (int [][] board , int n ) {
127
+ // Print the board in a nxn grid format
128
+ // if n=9, print the board in a 9x9 grid format
129
+ // if n=16, print the board in a 16x16 grid format
115
130
for (int r = 0 ; r < n ; r ++) {
116
131
for (int d = 0 ; d < n ; d ++) {
117
- System .out .print (board [r ][d ] + " " );
132
+ System .out .print (board [r ][d ]);
133
+ System .out .print (" " );
134
+ }
135
+ System .out .print ("\n " );
136
+
137
+ if ((r + 1 ) % (int ) Math .sqrt (n ) == 0 ) {
138
+ System .out .print ("" );
118
139
}
119
- System .out .println ();
120
140
}
121
141
}
122
142
123
143
/**
124
- * Demo runner
144
+ * The driver method to demonstrate solving a Sudoku puzzle.
145
+ * A sample 9x9 Sudoku puzzle is provided, and the program attempts to solve it
146
+ * using the `solveSudoku` method. If a solution is found, it is printed to the console.
147
+ *
148
+ * @param args Command-line arguments (not used in this program).
125
149
*/
126
150
public static void main (String [] args ) {
127
- int [][] board = {
151
+ int [][] board = new int [][] {
128
152
{3 , 0 , 6 , 5 , 0 , 8 , 4 , 0 , 0 },
129
153
{5 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 },
130
154
{0 , 8 , 7 , 0 , 0 , 0 , 0 , 3 , 1 },
0 commit comments