-1

I am trying to implement the Sudoku puzzle solver using Java but below code is failing on second case (it should return false). From the output being printed, it looks like the code exits even before the entire grid is solved. What am I missing?

Can someone help check this quickly and hint in case you see a problem.

Question: Write the function sudokuSolve that checks whether a given sudoku board (i.e. 9x9 sudoku puzzle) is solvable. If so, the function will returns true. Otherwise (i.e. there is no valid solution to the given sudoku board), returns false.

code:

public class Sudoku {
    static boolean sudokuSolve(char[][] board) {
        int row = -1, col = -1;
        List<Integer> candidates = null; // store smallest possible candidates
        for (int r = 0; r < 9; r++) {
            for (int c = 0; c < 9; c++) {
                if (board[r][c] == '.') {
                    List<Integer> newCandidates = getCandidates(board, r, c);
                    if (candidates == null || newCandidates.size() < candidates.size()) {
                        candidates = newCandidates;
                        row = r;
                        col = c;
                    }
                }
            }
        }
        if (candidates == null || candidates.isEmpty())
            return true;
        for (Integer val : candidates) {

            board[row][col] = (char) (val.intValue() + '0');
            if (sudokuSolve(board))
                return true;
            else
                board[row][col] = '.';
        }
        printGrid(board);
        return false;
    }

    /**
     * For each empty cell, consider 'newCandidates', the set of possible candidate
     * values that can be placed into that cell.
     * 
     */
    public static List<Integer> getCandidates(char[][] board, int x, int y) {
        // filled row numbers
        boolean[] mask = new boolean[10];
        for (int row = 0; row < 9; row++) {
            char ch = board[row][y];
            if (ch != '.')
                mask[ch - '0'] = true;
        }
        // filled col numbers
        for (int col = 0; col < 9; col++) {
            char ch = board[x][col];
            if (ch != '.')
                mask[ch - '0'] = true;
        }
        // filled subgrid numbers
        // starts at row - row%3, col - col%3
        int subBoardRow = x - (x % 3);
        int subBoardCol = y - (y % 3);
        for (int row = 0; row < 3; row++) {
            for (int col = 0; col < 3; col++) {
                char ch = board[subBoardRow + row][subBoardCol + col];
                if (ch != '.')
                    mask[ch - '0'] = true;
            }
        }

        List<Integer> candidates = new ArrayList<Integer>();
        for (int i = 1; i <= 9; i++) {
            if (!mask[i])
                candidates.add(i);
        }
        return candidates;
    }

      public static void main(String[] args) {
          char[][] board = new char[][] {
              {'.','.','.','7','.','.','3','.','1'},
              {'3','.','.','9','.','.','.','.','.'},
              {'.','4','.','3','1','.','2','.','.'},
              {'.','6','.','4','.','.','5','.','.'},
              {'.','.','.','.','.','.','.','.','.'},
              {'.','.','1','.','.','8','.','4','.'},
              {'.','.','6','.','2','1','.','5','.'},
              {'.','.','.','.','.','9','.','.','8'},
              {'8','.','5','.','.','4','.','.','.'}};

          System.out.println(sudokuSolve(board));
          printGrid(board);

          System.out.println("***************************************");

          char[][] board2 = new char[][] {
              {'.','8','9','.','4','.','6','.','5'},
              {'.','7','.','.','.','8','.','4','1'},
              {'5','6','.','9','.','.','.','.','8'},
              {'.','.','.','7','.','5','.','9','.'},
              {'.','9','.','4','.','1','.','5','.'},
              {'.','3','.','9','.','6','.','1','.'},
              {'8','.','.','.','.','.','.','.','7'},
              {'.','2','.','8','.','.','.','6','.'},
              {'.','.','6','.','7','.','.','8','.'}};
          System.out.println(sudokuSolve(board2));
          printGrid(board2);
      }

      public static void printGrid(char[][] grid) {
            for (int r = 0; r < grid.length; r++) {
                for (int c = 0; c < grid[0].length; c++) {
                    System.out.print(grid[r][c] + " ");
                }
                System.out.print("\n");
            }
        }

}

Output:

true
6 5 8 7 4 2 3 9 1 
3 1 2 9 8 6 4 7 5 
7 4 9 3 1 5 2 8 6 
2 6 3 4 9 7 5 . . 
. . . 1 . . . . . 
. . 1 2 . 8 . 4 . 
. . 6 8 2 1 . 5 . 
. . . 5 . 9 . . 8 
8 . 5 6 . 4 . . . 

***************************************

true 1 8 9 2 4 3 6 7 5 2 7 3 5 6 8 9 4 1 5 6 4 9 1 7 2 3 8 4 1 2 7 3 5 8 9 6 6 9 8 4 2 1 7 5 3 7 3 5 9 8 6 4 1 2 8 4 1 . 5 9 . 2 7 . 2 7 8 . . . 6 . . . 6 . 7 . . 8 .

3
  • Welcome to Stack Overflow! Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a minimal reproducible example. Use the edit link to improve your question - do not add more information via comments. Thanks! Commented Feb 25, 2018 at 18:17
  • Does not solve your problem, but you are processing the same grid two times. Change the second call to board2 like this System.out.println(sudokuSolve(board2)); and printGrid(board2); Commented Feb 25, 2018 at 18:43
  • also see stackoverflow.com/questions/4039594/… and any other sudoku solving related answers on SO in case they help with (re)designing the algorithm (sometimes you just have to scrap your original design instead of trying to fix it) Commented Mar 4, 2018 at 22:02

1 Answer 1

0

You algorithm is a little bit strange.

You have recursion, which seems useless. For every tile on the board you calculate candidates, but overwrite it with the candidates for another tile. Perhaps I'm wrong, but the result is sometimes true, where it shouldn't.
sudokuSolve cannot work correctly in this way.


UPDATE

The second initial board is wrong. There are two 9 in the 4. column (from beginning). Your algorithm cannot handle this case.

Either the question is wrong, or the question is to (also) implement a checker for the initial board, or you made a typo ;)

Sign up to request clarification or add additional context in comments.

1 Comment

The Recursion is for backtracking. Choose one of the candidates. With this as candidate try to solve the board. If it does not help solve the board, then backtrack and choose the next candidate. The test case (having 2 9s) was obtained from the website where I found the question as well. Perhaps the solution should handle that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.