patternjavaMajor
Sudoku Checker in Java
Viewed 0 times
sudokucheckerjava
Problem
public class SudokuChecker{
static int[][] sMatrix={
{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}
};
static int rSum=0;
static int cSum=0;
static int[] rSumArray=new int[9];
static int[] cSumArray=new int[9];
static int[] boxSumArray=new int[9];
static boolean checkArrayStatus(int[] rSumArray,int[] cSumArray,int[] boxSumArray)
{
int i=0;
boolean sudukoStatus=true;
while(i=3&&j=6&&j=3&&i=3&&i=3&&j=3&&i=6&&j=6)&&(j=6)&&(j>=3&&j=6)&&(j>=6))
{
boxSumArray[8]+=sMatrix[i][j];
}
}
}
if(checkArrayStatus(rSumArray,cSumArray,boxSumArray))
{
System.out.println("The matrix is sudoku compliant");
}
else
{
System.out.println("The matrix is not sudoku compliant");
}
}
}This a program which verifies if a 2D matrix is a Sudoku or not. The sum of every row, column and 3x3 matrices have to be 45. Please review the code and provide feedback on best practices and code optimization.
Solution
You have waaaay too many sums you are checking. KISS-Principle --> Keep it Simple {and} Stupid:
Short Explanation:
-
A Sudoku has three elements to validate. Each has to contain the single digit numbers from 1 to 9 exactly once.
-
These three elements are: each single row, each single column, the 9 3x3 sqares.
These elements are exactly mapped by the three variables you see in the for-loop.
-
Each of these elements is given to a validate function to verify, that it contains the numbers only once. Originally this was a golfed solution, so the square calculation is heavily algorithmic.
-
The validate function is quite simple. It initializes a counter to 0, and then walks the sorted "validated element" through, while always incrementing by 1. this gives the numbers from 1 to 9. In fact it is just a shortened for-loop, written a little different it's:
this one
Longer Explanation
How I got to the algorithmic generation for the squares:
This part is relatively simple. It gives the correct "column" by help of implicit integer conversion: The first part of the equation is a little difficult:
\$ (i / 3) \$
\$ {0,1,2} \mapsto 0 \$
\$ {3,4,5} \mapsto 1 \$
\$ {6,7,8} \mapsto 2 \$
take it
Now for the difficult one:
\$ (i * 3 \% 9) \$
\$ {0,3,6} \mapsto 0 \$
\$ {1,4,7} \mapsto 3 \$
\$ {2,5,8} \mapsto 6 \$
This one is for "jumping" the sqares vertically. Then we just have to iterate 0, 1, 2. This is accomplished by running the
private boolean checkSudokuStatus(int[][] grid) {
for (int i = 0; i < 9; i++) {
int[] row = new int[9];
int[] square = new int[9];
int[] column = grid[i].clone();
for (int j = 0; j < 9; j ++) {
row[j] = grid[j][i];
square[j] = grid[(i / 3) * 3 + j / 3][i * 3 % 9 + j % 3];
}
if (!(validate(column) && validate(row) && validate(square)))
return false;
}
return true;
}
private boolean validate(int[] check) {
int i = 0;
Arrays.sort(check);
for (int number : check) {
if (number != ++i)
return false;
}
return true;
}Short Explanation:
-
A Sudoku has three elements to validate. Each has to contain the single digit numbers from 1 to 9 exactly once.
-
These three elements are: each single row, each single column, the 9 3x3 sqares.
These elements are exactly mapped by the three variables you see in the for-loop.
-
Each of these elements is given to a validate function to verify, that it contains the numbers only once. Originally this was a golfed solution, so the square calculation is heavily algorithmic.
-
The validate function is quite simple. It initializes a counter to 0, and then walks the sorted "validated element" through, while always incrementing by 1. this gives the numbers from 1 to 9. In fact it is just a shortened for-loop, written a little different it's:
this one
for(int i = 1; i <= 9; i++){
if(check[i-1] != i){
return false;
}
}
return true;Longer Explanation
How I got to the algorithmic generation for the squares:
[(i / 3) * 3 + j / 3] [i * 3 % 9 + j % 3](i / 3) * 3 + j / 3This part is relatively simple. It gives the correct "column" by help of implicit integer conversion: The first part of the equation is a little difficult:
\$ (i / 3) \$
\$ {0,1,2} \mapsto 0 \$
\$ {3,4,5} \mapsto 1 \$
\$ {6,7,8} \mapsto 2 \$
take it
* 3 and you got the sqare you want to get in to. then if we now iterate row-wise, we need to jump to the next column every 3 Elements. That's done with j / 3.Now for the difficult one:
i * 3 % 9 + j % 3\$ (i * 3 \% 9) \$
\$ {0,3,6} \mapsto 0 \$
\$ {1,4,7} \mapsto 3 \$
\$ {2,5,8} \mapsto 6 \$
This one is for "jumping" the sqares vertically. Then we just have to iterate 0, 1, 2. This is accomplished by running the
% 3 operation.Code Snippets
private boolean checkSudokuStatus(int[][] grid) {
for (int i = 0; i < 9; i++) {
int[] row = new int[9];
int[] square = new int[9];
int[] column = grid[i].clone();
for (int j = 0; j < 9; j ++) {
row[j] = grid[j][i];
square[j] = grid[(i / 3) * 3 + j / 3][i * 3 % 9 + j % 3];
}
if (!(validate(column) && validate(row) && validate(square)))
return false;
}
return true;
}
private boolean validate(int[] check) {
int i = 0;
Arrays.sort(check);
for (int number : check) {
if (number != ++i)
return false;
}
return true;
}for(int i = 1; i <= 9; i++){
if(check[i-1] != i){
return false;
}
}
return true;[(i / 3) * 3 + j / 3] [i * 3 % 9 + j % 3](i / 3) * 3 + j / 3i * 3 % 9 + j % 3Context
StackExchange Code Review Q#46033, answer score: 28
Revisions (0)
No revisions yet.