Skip to content

Commit 1b999cf

Browse files
author
KaranMishra3610
committed
Refactor: Apply Iterator pattern to SudokuBoard
1 parent 8d8aa19 commit 1b999cf

File tree

1 file changed

+60
-36
lines changed
  • src/main/java/com/thealgorithms/puzzlesandgames

1 file changed

+60
-36
lines changed

src/main/java/com/thealgorithms/puzzlesandgames/Sudoku.java

Lines changed: 60 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,49 @@
1+
12
package com.thealgorithms.puzzlesandgames;
23

34
/**
45
* A class that provides methods to solve Sudoku puzzles of any n x n size
56
* using a backtracking approach, where n must be a perfect square.
67
* 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.
910
*/
10-
public final class Sudoku {
11+
final class Sudoku {
1112

1213
private Sudoku() {
13-
// prevent instantiation
1414
}
1515

1616
/**
1717
* 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).
1823
*
1924
* @param board The current state of the Sudoku board.
2025
* @param row The row index where the number is to be placed.
2126
* @param col The column index where the number is to be placed.
2227
* @param num The number to be placed on the board.
2328
* @return True if the placement is safe, otherwise false.
24-
* @throws ArrayIndexOutOfBoundsException if row/col are invalid
2529
*/
2630
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++) {
3533
if (board[row][d] == num) {
3634
return false;
3735
}
3836
}
3937

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++) {
4240
if (board[r][col] == num) {
4341
return false;
4442
}
4543
}
4644

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);
4947
int boxRowStart = row - row % sqrt;
5048
int boxColStart = col - col % sqrt;
5149

@@ -62,21 +60,27 @@ public static boolean isSafe(int[][] board, int row, int col, int num) {
6260

6361
/**
6462
* 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.
6573
*
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.
6977
*/
7078
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;
7781
boolean isEmpty = true;
7882

79-
// find next empty cell
83+
// Find the next empty cell
8084
for (int i = 0; i < n; i++) {
8185
for (int j = 0; j < n; j++) {
8286
if (board[i][j] == 0) {
@@ -86,45 +90,65 @@ public static boolean solveSudoku(int[][] board, int n) {
8690
break;
8791
}
8892
}
89-
if (!isEmpty) break;
93+
if (!isEmpty) {
94+
break;
95+
}
9096
}
9197

92-
// no empty cell left = solved
98+
// No empty space left
9399
if (isEmpty) {
94100
return true;
95101
}
96102

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.
98105
for (int num = 1; num <= n; num++) {
99106
if (isSafe(board, row, col, num)) {
100107
board[row][col] = num;
101108
if (solveSudoku(board, n)) {
102109
return true;
103110
} else {
104-
board[row][col] = 0; // backtrack
111+
// replace it
112+
board[row][col] = 0;
105113
}
106114
}
107115
}
108116
return false;
109117
}
110118

111119
/**
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).
113125
*/
114126
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
115130
for (int r = 0; r < n; r++) {
116131
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("");
118139
}
119-
System.out.println();
120140
}
121141
}
122142

123143
/**
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).
125149
*/
126150
public static void main(String[] args) {
127-
int[][] board = {
151+
int[][] board = new int[][] {
128152
{3, 0, 6, 5, 0, 8, 4, 0, 0},
129153
{5, 2, 0, 0, 0, 0, 0, 0, 0},
130154
{0, 8, 7, 0, 0, 0, 0, 3, 1},

0 commit comments

Comments
 (0)