简体   繁体   中英

'2D' Array Sudoku Puzzle Check with enum. Cannot understand the flow of my own program despite debugging

I am programming a simple (or so I thought!) Checker for Sudoku puzzles using a '2D' array and an enum. The program successfully checks the grid and reports "Solution Okay!" - but it has a strange 'side effect - it prints out "invalid ROW 4" and "invalid COLUMN 1". I am new to programming and despite best efforts debugging I cannot find a solution.

(This problem was taken from CS106A Stanford University course- there are suggested solutions but I want to understand the flaw in my own code. I know it's a dirty solution and perhaps not a good example of programming. All feedback welcome.)

ROWS 1 Vaild
ROWS 2 Vaild
ROWS 3 Vaild
ROWS invalid! number: 4
ROWS 4 Vaild
ROWS 5 Vaild
ROWS 6 Vaild
ROWS 7 Vaild
ROWS 8 Vaild
ROWS 9 Vaild
All ROWS Valid
COLUMNS invalid! number: 1
COLUMNS 1 Vaild
COLUMNS 2 Vaild
COLUMNS 3 Vaild
COLUMNS 4 Vaild
COLUMNS 5 Vaild
COLUMNS 6 Vaild
COLUMNS 7 Vaild
COLUMNS 8 Vaild
COLUMNS 9 Vaild
All COLUMNS Valid
Solution Okay! 

Separate file but same package

public enum Direction{
    ROWS,COLUMNS,SQUARES
}

//end of enum

//import java.util.zip.Checksum;

import acm.program.ConsoleProgram;

/**
 * Program that receives in a grid and checks that it is a valid sudoku solution
 * 
 *
 */


public class SudokuTest extends ConsoleProgram  {


static boolean result;
Direction direction;

    public static void main(String args[]){

        int[][] grid = new int[][]{
                {2,5,7,9,6,4,1,8,3},
                {4,9,1,8,7,3,6,5,2},
                {3,8,6,1,2,5,9,4,7},
                {6,4,5,7,3,2,8,1,9},
                {7,1,9,5,4,8,3,2,6},
                {8,3,2,6,1,9,5,7,4},
                {1,6,3,2,5,7,4,9,8},
                {5,7,8,4,9,6,2,3,1},
                {9,2,4,3,8,1,7,6,5}
                };

        SudokuTest st = new SudokuTest();
        result = st.checkSudokuSolution(grid);
        System.out.println("The solution is correct: " + result);


    }
    private boolean checkSudokuSolution(int[][] grid){

        //test works with line below

        boolean allRowsOkay = checkElement(grid,direction.ROWS);
        boolean allCOlumnsOkay = checkElement(grid,direction.COLUMNS);

        if(allCOlumnsOkay&allCOlumnsOkay==true){
        System.out.println("Solution Okay! ");
        return true;
    }
    else
        return false;
}

    private boolean checkElement(int[][] grid,Direction direction) {
        boolean []hist =new boolean[10];
        int value=0; //value of the current entry
        int elementCount=0;
        int count=1;
        int i;
        int j;

        //program using histogram type solution
        //Check rows first - need to consider whether code can be reused for columns

        for(i=0;i<=8;i++){
            for(j=0;j<=8;j++){

        if(direction == direction.ROWS)     
                {
            value = grid[i][j];
            }


        else if(direction == direction.COLUMNS) {
            value = grid[j][i];
            }
        else {

            break;
        }

                hist[value] = true;


        //can i reuse code for row and column?
            if(hist[1]&hist[2]&hist[3]&hist[4]&hist[5]&hist[6]&hist[7]&hist[8]&hist[9]==true) {

                System.out.println("" + direction +" "+(i+1) + " Vaild");
                elementCount++;
                hist = new boolean[10];
                }

            else if(hist[1]&hist[2]&hist[3]&hist[4]&hist[5]&hist[6]&hist[7]&hist[8]&hist[9]==false)  {

                System.out.println(direction + " invalid! " + "number: " + (i+1));

            }

            }
            hist = new boolean[10];
        }

        if(elementCount==9)System.out.println("All " + direction + " Valid");



        if(elementCount==9)return true;
        else return false;

        }
    }

The statements checking the 'hits' array are very poorly formatted. the & operator is a bitwise AND. I expect you mean this to be '&&` which is logical AND. Also, in general, you don't need to compare a boolean value to true or false.

So your comparisons should read something like:

if ( hist[1] && hist[2] && ... && hist[9]) {
    ...
} else {
    ...
}

Secondly, you are running these checks 9 times per row or column (I think that's right - the indenting is mixed up so it's hard to tell). You should be running these checks outside your j for loop. In other words, it should build the hist array completely for a row or column and then check whether all 9 values are accounted for.

There are many other stylistic errors and possible logic errors but these seem to me to be the first things to fix.

Sorry, but if you can't understand your own code, it's time to re-write it. If this were my project, I'd try to divide and conquer by:

  • I'd fill the value array just as you're doing, within two nested for loops
  • But that's all I'd do inside of those loops. This will keep my code simpler and make it easier to understand and to solve the problem.
  • I'd analyze the value array after adding all the data to it, meaning after both nested for loops have concluded, not as you're doing it inside of the for loops.
  • I would create a separate method to analyze a single row/column or 9 value square
  • I'd have my checkElement method call these guys in a for loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM