From 66a771b9e2ff2b64f18b97118c863ebd214e9d5c Mon Sep 17 00:00:00 2001 From: khalidx3 Date: Sat, 4 Oct 2025 17:24:22 +0530 Subject: [PATCH 1/6] Add Sudoku Solver refactored to pass Build and Clang Format --- .../backtracking/SudokuSolver.java | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 src/main/java/com/thealgorithms/backtracking/SudokuSolver.java diff --git a/src/main/java/com/thealgorithms/backtracking/SudokuSolver.java b/src/main/java/com/thealgorithms/backtracking/SudokuSolver.java new file mode 100644 index 000000000000..7f4593bc7804 --- /dev/null +++ b/src/main/java/com/thealgorithms/backtracking/SudokuSolver.java @@ -0,0 +1,94 @@ +package main.java.com.thealgorithms.backtracking; + +/** + * Sudoku Solver using Backtracking Algorithm + * + * Solves a 9x9 Sudoku puzzle. All methods are static and class is final to + * match + * TheAlgorithms/Java repo conventions. + */ +public final class SudokuSolver { + + private SudokuSolver() { + } // Prevent instantiation + + /** + * Solves the Sudoku puzzle using backtracking. + * + * @param sudoku 9x9 Sudoku grid, empty cells are 0 + * @param row current row + * @param col current column + * @return true if solved, false otherwise + */ + public static boolean sudokuSolver(int[][] sudoku, int row, int col) { + if (row == 9) { + return true; + } + + int nextRow = row; + int nextCol = col + 1; + if (nextCol == 9) { + nextRow = row + 1; + nextCol = 0; + } + + if (sudoku[row][col] != 0) { + return sudokuSolver(sudoku, nextRow, nextCol); + } + + for (int num = 1; num <= 9; num++) { + if (isSafe(sudoku, row, col, num)) { + sudoku[row][col] = num; + if (sudokuSolver(sudoku, nextRow, nextCol)) { + return true; + } + sudoku[row][col] = 0; // backtrack + } + } + + return false; + } + + /** + * Checks if placing num at (row, col) is safe. + * + * @param sudoku 9x9 Sudoku grid + * @param row current row + * @param col current column + * @param num number to place + * @return true if safe, false otherwise + */ + private static boolean isSafe(int[][] sudoku, int row, int col, int num) { + for (int i = 0; i < 9; i++) { + if (sudoku[row][i] == num || sudoku[i][col] == num) { + return false; + } + } + + int startRow = row - row % 3; + int startCol = col - col % 3; + for (int i = startRow; i < startRow + 3; i++) { + for (int j = startCol; j < startCol + 3; j++) { + if (sudoku[i][j] == num) { + return false; + } + } + } + + return true; + } + + /** + * Prints the Sudoku grid. + * + * @param sudoku 9x9 Sudoku grid + */ + public static void printSudoku(int[][] sudoku) { + for (int i = 0; i < 9; i++) { + for (int j = 0; j < 9; j++) { + System.out.print(sudoku[i][j] + " "); + } + System.out.println(); + } + } +} From f8b35c03c0703ddd1e66c1f1529b7e7949b456c6 Mon Sep 17 00:00:00 2001 From: khalidx3 Date: Sat, 4 Oct 2025 17:28:19 +0530 Subject: [PATCH 2/6] Fixed Clang Format issues --- .../backtracking/SudokuSolver.java | 138 +++++++++--------- 1 file changed, 69 insertions(+), 69 deletions(-) diff --git a/src/main/java/com/thealgorithms/backtracking/SudokuSolver.java b/src/main/java/com/thealgorithms/backtracking/SudokuSolver.java index 7f4593bc7804..f38d96eabdeb 100644 --- a/src/main/java/com/thealgorithms/backtracking/SudokuSolver.java +++ b/src/main/java/com/thealgorithms/backtracking/SudokuSolver.java @@ -9,86 +9,86 @@ */ public final class SudokuSolver { - private SudokuSolver() { - } // Prevent instantiation + private SudokuSolver() { + } // Prevent instantiation - /** - * Solves the Sudoku puzzle using backtracking. - * - * @param sudoku 9x9 Sudoku grid, empty cells are 0 - * @param row current row - * @param col current column - * @return true if solved, false otherwise - */ - public static boolean sudokuSolver(int[][] sudoku, int row, int col) { - if (row == 9) { - return true; - } + /** + * Solves the Sudoku puzzle using backtracking. + * + * @param sudoku 9x9 Sudoku grid, empty cells are 0 + * @param row current row + * @param col current column + * @return true if solved, false otherwise + */ + public static boolean sudokuSolver(int[][] sudoku, int row, int col) { + if (row == 9) { + return true; + } - int nextRow = row; - int nextCol = col + 1; - if (nextCol == 9) { - nextRow = row + 1; - nextCol = 0; - } + int nextRow = row; + int nextCol = col + 1; + if (nextCol == 9) { + nextRow = row + 1; + nextCol = 0; + } - if (sudoku[row][col] != 0) { - return sudokuSolver(sudoku, nextRow, nextCol); - } + if (sudoku[row][col] != 0) { + return sudokuSolver(sudoku, nextRow, nextCol); + } - for (int num = 1; num <= 9; num++) { - if (isSafe(sudoku, row, col, num)) { - sudoku[row][col] = num; - if (sudokuSolver(sudoku, nextRow, nextCol)) { - return true; - } - sudoku[row][col] = 0; // backtrack - } + for (int num = 1; num <= 9; num++) { + if (isSafe(sudoku, row, col, num)) { + sudoku[row][col] = num; + if (sudokuSolver(sudoku, nextRow, nextCol)) { + return true; + } + sudoku[row][col] = 0; // backtrack } + } - return false; - } + return false; + } - /** - * Checks if placing num at (row, col) is safe. - * - * @param sudoku 9x9 Sudoku grid - * @param row current row - * @param col current column - * @param num number to place - * @return true if safe, false otherwise - */ - private static boolean isSafe(int[][] sudoku, int row, int col, int num) { - for (int i = 0; i < 9; i++) { - if (sudoku[row][i] == num || sudoku[i][col] == num) { - return false; - } + /** + * Checks if placing num at (row, col) is safe. + * + * @param sudoku 9x9 Sudoku grid + * @param row current row + * @param col current column + * @param num number to place + * @return true if safe, false otherwise + */ + private static boolean isSafe(int[][] sudoku, int row, int col, int num) { + for (int i = 0; i < 9; i++) { + if (sudoku[row][i] == num || sudoku[i][col] == num) { + return false; } + } - int startRow = row - row % 3; - int startCol = col - col % 3; - for (int i = startRow; i < startRow + 3; i++) { - for (int j = startCol; j < startCol + 3; j++) { - if (sudoku[i][j] == num) { - return false; - } - } + int startRow = row - row % 3; + int startCol = col - col % 3; + for (int i = startRow; i < startRow + 3; i++) { + for (int j = startCol; j < startCol + 3; j++) { + if (sudoku[i][j] == num) { + return false; + } } + } - return true; - } + return true; + } - /** - * Prints the Sudoku grid. - * - * @param sudoku 9x9 Sudoku grid - */ - public static void printSudoku(int[][] sudoku) { - for (int i = 0; i < 9; i++) { - for (int j = 0; j < 9; j++) { - System.out.print(sudoku[i][j] + " "); - } - System.out.println(); + /** + * Prints the Sudoku grid. + * + * @param sudoku 9x9 Sudoku grid + */ + public static void printSudoku(int[][] sudoku) { + for (int i = 0; i < 9; i++) { + for (int j = 0; j < 9; j++) { + System.out.print(sudoku[i][j] + " "); } - } + System.out.println(); + } + } } From f9f8ea30109952d959d30923b9fa6edad74c3b02 Mon Sep 17 00:00:00 2001 From: khalidx3 Date: Tue, 7 Oct 2025 23:53:02 +0530 Subject: [PATCH 3/6] Add SudokuSolverTt test file --- .../backtracking/SudokuSolverTest.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/test/java/com/thealgorithms/backtracking/SudokuSolverTest.java diff --git a/src/test/java/com/thealgorithms/backtracking/SudokuSolverTest.java b/src/test/java/com/thealgorithms/backtracking/SudokuSolverTest.java new file mode 100644 index 000000000000..c675cb39b05c --- /dev/null +++ b/src/test/java/com/thealgorithms/backtracking/SudokuSolverTest.java @@ -0,0 +1,35 @@ +package test.java.com.thealgorithms.backtracking; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class SudokuSolverTest { + + @Test + public void testSudokuSolverSolvesValidBoard() { + int[][] sudoku = { + { 3, 0, 6, 5, 0, 8, 4, 0, 0 }, + { 5, 2, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 8, 7, 0, 0, 0, 0, 3, 1 }, + { 0, 0, 3, 0, 1, 0, 0, 8, 0 }, + { 9, 0, 0, 8, 6, 3, 0, 0, 5 }, + { 0, 5, 0, 0, 9, 0, 6, 0, 0 }, + { 1, 3, 0, 0, 0, 0, 2, 5, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 7, 4 }, + { 0, 0, 5, 2, 0, 6, 3, 0, 0 } + }; + + boolean solved = SudokuSolver.sudokuSolver(sudoku, 0, 0); + assertTrue(solved, "SudokuSolver should solve a valid board"); + } + + @Test + public void testSudokuSolverRejectsInvalidBoard() { + int[][] sudoku = new int[9][9]; + sudoku[0][0] = 5; + sudoku[0][1] = 5; // invalid duplicate in row + + boolean solved = SudokuSolver.sudokuSolver(sudoku, 0, 0); + assertFalse(solved, "SudokuSolver should not solve an invalid board"); + } +} From 369f33d0c865731ba895a55f2a53317b0a08b8f1 Mon Sep 17 00:00:00 2001 From: khalidx3 Date: Wed, 8 Oct 2025 00:11:27 +0530 Subject: [PATCH 4/6] Add JUnit test for Sudoku Solver --- .../com/thealgorithms/backtracking/SudokuSolverTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/thealgorithms/backtracking/SudokuSolverTest.java b/src/test/java/com/thealgorithms/backtracking/SudokuSolverTest.java index c675cb39b05c..ee53ea58aef5 100644 --- a/src/test/java/com/thealgorithms/backtracking/SudokuSolverTest.java +++ b/src/test/java/com/thealgorithms/backtracking/SudokuSolverTest.java @@ -1,7 +1,8 @@ -package test.java.com.thealgorithms.backtracking; +package com.thealgorithms.backtracking; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; public class SudokuSolverTest { From 7c8adc1cad3dbfa377bf02720e33be16f44e7e39 Mon Sep 17 00:00:00 2001 From: khalidx3 Date: Wed, 8 Oct 2025 00:13:59 +0530 Subject: [PATCH 5/6] Refactor Sudoku Solver and test to pass Build and Clang Format --- .../backtracking/SudokuSolverTest.java | 38 +++++++------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/src/test/java/com/thealgorithms/backtracking/SudokuSolverTest.java b/src/test/java/com/thealgorithms/backtracking/SudokuSolverTest.java index ee53ea58aef5..a63627fdf894 100644 --- a/src/test/java/com/thealgorithms/backtracking/SudokuSolverTest.java +++ b/src/test/java/com/thealgorithms/backtracking/SudokuSolverTest.java @@ -6,31 +6,21 @@ public class SudokuSolverTest { - @Test - public void testSudokuSolverSolvesValidBoard() { - int[][] sudoku = { - { 3, 0, 6, 5, 0, 8, 4, 0, 0 }, - { 5, 2, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 8, 7, 0, 0, 0, 0, 3, 1 }, - { 0, 0, 3, 0, 1, 0, 0, 8, 0 }, - { 9, 0, 0, 8, 6, 3, 0, 0, 5 }, - { 0, 5, 0, 0, 9, 0, 6, 0, 0 }, - { 1, 3, 0, 0, 0, 0, 2, 5, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 7, 4 }, - { 0, 0, 5, 2, 0, 6, 3, 0, 0 } - }; + @Test + public void testSudokuSolverSolvesValidBoard() { + int[][] sudoku = {{3, 0, 6, 5, 0, 8, 4, 0, 0}, {5, 2, 0, 0, 0, 0, 0, 0, 0}, {0, 8, 7, 0, 0, 0, 0, 3, 1}, {0, 0, 3, 0, 1, 0, 0, 8, 0}, {9, 0, 0, 8, 6, 3, 0, 0, 5}, {0, 5, 0, 0, 9, 0, 6, 0, 0}, {1, 3, 0, 0, 0, 0, 2, 5, 0}, {0, 0, 0, 0, 0, 0, 0, 7, 4}, {0, 0, 5, 2, 0, 6, 3, 0, 0}}; - boolean solved = SudokuSolver.sudokuSolver(sudoku, 0, 0); - assertTrue(solved, "SudokuSolver should solve a valid board"); - } + boolean solved = SudokuSolver.sudokuSolver(sudoku, 0, 0); + assertTrue(solved, "SudokuSolver should solve a valid board"); + } - @Test - public void testSudokuSolverRejectsInvalidBoard() { - int[][] sudoku = new int[9][9]; - sudoku[0][0] = 5; - sudoku[0][1] = 5; // invalid duplicate in row + @Test + public void testSudokuSolverRejectsInvalidBoard() { + int[][] sudoku = new int[9][9]; + sudoku[0][0] = 5; + sudoku[0][1] = 5; // invalid duplicate in row - boolean solved = SudokuSolver.sudokuSolver(sudoku, 0, 0); - assertFalse(solved, "SudokuSolver should not solve an invalid board"); - } + boolean solved = SudokuSolver.sudokuSolver(sudoku, 0, 0); + assertFalse(solved, "SudokuSolver should not solve an invalid board"); + } } From 7490ad59146af840f99a2c3a45fde8ea65c4f2e9 Mon Sep 17 00:00:00 2001 From: khalidx3 Date: Wed, 8 Oct 2025 00:21:10 +0530 Subject: [PATCH 6/6] Add minimal JUnit test for SudokuSolver --- .../backtracking/SudokuSolverTest.java | 35 +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/src/test/java/com/thealgorithms/backtracking/SudokuSolverTest.java b/src/test/java/com/thealgorithms/backtracking/SudokuSolverTest.java index a63627fdf894..0508c7ac3b3c 100644 --- a/src/test/java/com/thealgorithms/backtracking/SudokuSolverTest.java +++ b/src/test/java/com/thealgorithms/backtracking/SudokuSolverTest.java @@ -1,26 +1,23 @@ package com.thealgorithms.backtracking; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; - +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; public class SudokuSolverTest { - @Test - public void testSudokuSolverSolvesValidBoard() { - int[][] sudoku = {{3, 0, 6, 5, 0, 8, 4, 0, 0}, {5, 2, 0, 0, 0, 0, 0, 0, 0}, {0, 8, 7, 0, 0, 0, 0, 3, 1}, {0, 0, 3, 0, 1, 0, 0, 8, 0}, {9, 0, 0, 8, 6, 3, 0, 0, 5}, {0, 5, 0, 0, 9, 0, 6, 0, 0}, {1, 3, 0, 0, 0, 0, 2, 5, 0}, {0, 0, 0, 0, 0, 0, 0, 7, 4}, {0, 0, 5, 2, 0, 6, 3, 0, 0}}; - - boolean solved = SudokuSolver.sudokuSolver(sudoku, 0, 0); - assertTrue(solved, "SudokuSolver should solve a valid board"); - } - - @Test - public void testSudokuSolverRejectsInvalidBoard() { - int[][] sudoku = new int[9][9]; - sudoku[0][0] = 5; - sudoku[0][1] = 5; // invalid duplicate in row - - boolean solved = SudokuSolver.sudokuSolver(sudoku, 0, 0); - assertFalse(solved, "SudokuSolver should not solve an invalid board"); - } + @Test + void testSudokuSolver() { + int[][] sudoku = { + { 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 } + }; + assertTrue(SudokuSolver.sudokuSolver(sudoku, 0, 0)); + } }