1
1
package com .thealgorithms .others ;
2
2
3
+ /**
4
+ * A class that provides methods to solve Sudoku puzzles of any n x n size
5
+ * using a backtracking approach, where n must be a perfect square.
6
+ * The algorithm checks for safe number placements in rows, columns,
7
+ * and subgrids (which are sqrt(n) x sqrt(n) in size) and recursively solves the puzzle.
8
+ * Though commonly used for 9x9 grids, it is adaptable to other valid Sudoku dimensions.
9
+ */
3
10
final class Sudoku {
11
+
4
12
private Sudoku () {
5
13
}
6
14
15
+ /**
16
+ * Checks if placing a number in a specific position on the Sudoku board is safe.
17
+ * The number is considered safe if it does not violate any of the Sudoku rules:
18
+ * - It should not be present in the same row.
19
+ * - It should not be present in the same column.
20
+ * - It should not be present in the corresponding 3x3 subgrid.
21
+ * - 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).
22
+ *
23
+ * @param board The current state of the Sudoku board.
24
+ * @param row The row index where the number is to be placed.
25
+ * @param col The column index where the number is to be placed.
26
+ * @param num The number to be placed on the board.
27
+ * @return True if the placement is safe, otherwise false.
28
+ */
7
29
public static boolean isSafe (int [][] board , int row , int col , int num ) {
8
- // Row has the unique ( row-clash)
30
+ // Check the row for duplicates
9
31
for (int d = 0 ; d < board .length ; d ++) {
10
- // Check if the number we are trying to
11
- // place is already present in
12
- // that row, return false;
13
32
if (board [row ][d ] == num ) {
14
33
return false ;
15
34
}
16
35
}
17
36
18
- // Column has the unique numbers (column-clash)
37
+ // Check the column for duplicates
19
38
for (int r = 0 ; r < board .length ; r ++) {
20
- // Check if the number
21
- // we are trying to
22
- // place is already present in
23
- // that column, return false;
24
39
if (board [r ][col ] == num ) {
25
40
return false ;
26
41
}
27
42
}
28
43
29
- // Corresponding square has
30
- // unique number (box-clash)
44
+ // Check the corresponding 3x3 subgrid for duplicates
31
45
int sqrt = (int ) Math .sqrt (board .length );
32
46
int boxRowStart = row - row % sqrt ;
33
47
int boxColStart = col - col % sqrt ;
@@ -40,22 +54,37 @@ public static boolean isSafe(int[][] board, int row, int col, int num) {
40
54
}
41
55
}
42
56
43
- // if there is no clash, it's safe
44
57
return true ;
45
58
}
46
59
60
+ /**
61
+ * Solves the Sudoku puzzle using backtracking.
62
+ * The algorithm finds an empty cell and tries placing numbers
63
+ * from 1 to n, where n is the size of the board
64
+ * (for example, from 1 to 9 in a standard 9x9 Sudoku).
65
+ * The algorithm finds an empty cell and tries placing numbers from 1 to 9.
66
+ * The standard version of Sudoku uses numbers from 1 to 9, so the algorithm can be
67
+ * easily modified for other variations of the game.
68
+ * If a number placement is valid (checked via `isSafe`), the number is
69
+ * placed and the function recursively attempts to solve the rest of the puzzle.
70
+ * If no solution is possible, the number is removed (backtracked),
71
+ * and the process is repeated.
72
+ *
73
+ * @param board The current state of the Sudoku board.
74
+ * @param n The size of the Sudoku board (typically 9 for a standard puzzle).
75
+ * @return True if the Sudoku puzzle is solvable, false otherwise.
76
+ */
47
77
public static boolean solveSudoku (int [][] board , int n ) {
48
78
int row = -1 ;
49
79
int col = -1 ;
50
80
boolean isEmpty = true ;
81
+
82
+ // Find the next empty cell
51
83
for (int i = 0 ; i < n ; i ++) {
52
84
for (int j = 0 ; j < n ; j ++) {
53
85
if (board [i ][j ] == 0 ) {
54
86
row = i ;
55
87
col = j ;
56
-
57
- // We still have some remaining
58
- // missing values in Sudoku
59
88
isEmpty = false ;
60
89
break ;
61
90
}
@@ -70,12 +99,12 @@ public static boolean solveSudoku(int[][] board, int n) {
70
99
return true ;
71
100
}
72
101
73
- // Else for each-row backtrack
102
+ // Try placing numbers 1 to n in the empty cell (n should be a perfect square)
103
+ // Eg: n=9 for a standard 9x9 Sudoku puzzle, n=16 for a 16x16 puzzle, etc.
74
104
for (int num = 1 ; num <= n ; num ++) {
75
105
if (isSafe (board , row , col , num )) {
76
106
board [row ][col ] = num ;
77
107
if (solveSudoku (board , n )) {
78
- // print(board, n);
79
108
return true ;
80
109
} else {
81
110
// replace it
@@ -86,8 +115,17 @@ public static boolean solveSudoku(int[][] board, int n) {
86
115
return false ;
87
116
}
88
117
118
+ /**
119
+ * Prints the current state of the Sudoku board in a readable format.
120
+ * Each row is printed on a new line, with numbers separated by spaces.
121
+ *
122
+ * @param board The current state of the Sudoku board.
123
+ * @param n The size of the Sudoku board (typically 9 for a standard puzzle).
124
+ */
89
125
public static void print (int [][] board , int n ) {
90
- // We got the answer, just print it
126
+ // Print the board in a nxn grid format
127
+ // if n=9, print the board in a 9x9 grid format
128
+ // if n=16, print the board in a 16x16 grid format
91
129
for (int r = 0 ; r < n ; r ++) {
92
130
for (int d = 0 ; d < n ; d ++) {
93
131
System .out .print (board [r ][d ]);
@@ -101,7 +139,13 @@ public static void print(int[][] board, int n) {
101
139
}
102
140
}
103
141
104
- // Driver Code
142
+ /**
143
+ * The driver method to demonstrate solving a Sudoku puzzle.
144
+ * A sample 9x9 Sudoku puzzle is provided, and the program attempts to solve it
145
+ * using the `solveSudoku` method. If a solution is found, it is printed to the console.
146
+ *
147
+ * @param args Command-line arguments (not used in this program).
148
+ */
105
149
public static void main (String [] args ) {
106
150
int [][] board = new int [][] {
107
151
{3 , 0 , 6 , 5 , 0 , 8 , 4 , 0 , 0 },
@@ -117,7 +161,6 @@ public static void main(String[] args) {
117
161
int n = board .length ;
118
162
119
163
if (solveSudoku (board , n )) {
120
- // print solution
121
164
print (board , n );
122
165
} else {
123
166
System .out .println ("No solution" );
0 commit comments