HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMajor

Sudoku Checker in Java

Submitted by: @import:stackexchange-codereview··
0
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:

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 / 3


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 * 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 / 3
i * 3 % 9 + j % 3

Context

StackExchange Code Review Q#46033, answer score: 28

Revisions (0)

No revisions yet.