Sudoku Checker and Solver
Sudoku is a puzzle where we need to fill a 9×9 grid with digits from 1 to 9 such that each column, each row, and each of the nine 3×3 blocks contains all of the 1-9 digits.
Sudoku Checker
The problem is to check whether a given 9×9 array of integers from 1 to 9 is a valid solution to a Sudoku puzzle. For example, the following is a valid solution:
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 9
import java.util.Arrays;
public class SudokoChecker
{
public static boolean check(int[][] arr)
{
if (arr.length != 9)
return false;
for (int i = 0; i < 9; i++)
{
if (arr[i].length != 9)
return false;
for (int j = 0; j < 9; j++)
if (arr[i][j] < 1 || arr[i][j] > 9)
return false;
}
int[] counts = new int[9];
int good_count = 0;
Arrays.fill(counts, 0);
// rows
for (int i = 0; i < 9; i++)
{
good_count++;
for (int j = 0; j < 9; j++)
{
counts[arr[i][j] - 1]++;
if (counts[arr[i][j] - 1] != good_count)
return false;
}
}
// columns
for (int j = 0; j < 9; j++)
{
good_count++;
for (int i = 0; i < 9; i++)
{
counts[arr[i][j] - 1]++;
if (counts[arr[i][j] - 1] != good_count)
return false;
}
}
// blocks
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
good_count++;
for (int r = i * 3; r < i * 3 + 3; r++)
{
for (int c = j * 3; c < j * 3 + 3; c++)
{
counts[arr[r][c] - 1]++;
if (counts[arr[r][c] - 1] != good_count)
return false;
}
}
}
}
return true;
}
public static void main(String[] args)
{
int[][] arr =
{
{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, 9}
};
System.out.println(check(arr));
}
}
Sudoku Solver
Given a Sudoku puzzle represented by a 9-by-9 array of integers from 0 to 9, find a solution by replacing all 0’s with a number from 1 to 9: each row, column, and block should contain each integer from 1 to 9 exactly once. The 0’s are placeholders, representing the blank spaces.
import java.util.Arrays;
public class SudokuSolver
{
public static boolean isValid(int i, int j, int v, int[][] arr)
{
for (int k = 0; k < 9; k++) // row
if (v == arr[i][k])
return false;
for (int k = 0; k < 9; k++) // column
if (v == arr[k][j])
return false;
int r = (i / 3) * 3;
int c = (j / 3) * 3;
for (int k = 0; k < 3; ++k) // box
for (int m = 0; m < 3; ++m)
if (v == arr[r + k][c + m])
return false;
return true; // valid
}
public static boolean solve(int[][] arr)
{
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
if (arr[i][j] != 0)
continue;
for (int v = 1; v <= 9; v++)
{
if (isValid(i, j, v, arr))
{
arr[i][j] = v;
if (solve(arr))
return true;
}
}
arr[i][j] = 0; // reset backtrack
return false;
}
}
return true;
}
public static void main(String[] args)
{
int[][] arr =
{
{0, 0, 0, 6, 7, 8, 9, 1, 2},
{0, 7, 2, 0, 9, 5, 3, 4, 8},
{0, 9, 8, 3, 0, 2, 5, 6, 7},
{8, 0, 9, 7, 6, 0, 4, 2, 3},
{4, 2, 0, 8, 5, 3, 0, 9, 1},
{7, 1, 3, 0, 2, 4, 8, 0, 6},
{9, 6, 1, 5, 0, 7, 2, 8, 0},
{2, 8, 7, 4, 1, 0, 6, 3, 0},
{3, 4, 5, 2, 8, 6, 0, 0, 0}
};
if (!solve(arr))
System.out.println("no solution");
else
for (int i = 0; i < arr.length; i++)
System.out.println(Arrays.toString(arr[i]));
}
}
The solve method above can be replaced by the following one, which is more efficient by avoid redundant checks. The method should be called using “solve(0, 0, arr)”.
public static boolean solve(int i, int j, int[][] arr)
{
int next_i = i;
int next_j = j;
if (j == 8)
{ // next row
next_i = i + 1;
next_j = 0;
}
else
next_j = j + 1;
// skip
if (arr[i][j] != 0)
{
if (next_i == 9)
return true;
return solve(next_i, next_j, arr);
}
// fill up
for (int v = 1; v <= 9; v++)
{
if (isValid(i, j, v, arr))
{
arr[i][j] = v;
if (next_i == 9)
return true;
if (solve(next_i, next_j, arr))
return true;
}
}
// reset for backtrack
arr[i][j] = 0;
return false;
}