Home > OS >  Sudoku Solver in Python keeps outputting FALSE solution
Sudoku Solver in Python keeps outputting FALSE solution

Time:10-03

As title mentioned. Obviously, the code stoped at the second ROW of the output board.I have been checking it for more than a hundred times but I still could not find where it goes wrong. I would be so grateful if you guys can tell me where I did wrong. Below is my code.

def solve(board):

    if not find_zero(board):
        return True
    else:
        row, col = find_zero(board)

    for value in range(1, 10):
        if is_valid(board, row, col, value):
            board[row][col] = value
            if solve(board):
                return True
        board[row][col] == 0

    return False


def find_zero(board):
    for i in range(9):
        for j in range(9):
            if board[i][j] == 0:
                return i, j
    return None, None


def is_valid(board, row, col, value):

    # Check the row
    if value in board[row]:
        return False
        
    # Check the column
    col_vals = [board[i][col] for i in range(9)]
    if value in col_vals:
        return False

    # Check the grid
    x = (row // 3) * 3
    y = (col // 3) * 3

    for i in range(x, x   3):
        for j in range(y, y   3):
            if board[i][j] == value:
                return False

    return True

Here is the board and the output of my code.

board = [
    [5, 3, 0, 0, 7, 0, 0, 0, 0],
    [6, 0, 0, 1, 9, 5, 0, 0, 0],
    [0, 9, 8, 0, 0, 0, 0, 6, 0],
    [8, 0, 0, 0, 6, 0, 0, 0, 3],
    [4, 0, 0, 8, 0, 3, 0, 0, 1],
    [7, 0, 0, 0, 2, 0, 0, 0, 6],
    [0, 6, 0, 0, 0, 0, 2, 8, 0],
    [0, 0, 0, 4, 1, 9, 0, 0, 5],
    [0, 0, 0, 0, 8, 0, 0, 7, 9],
]

False
[5, 3, 1, 2, 7, 6, 8, 9, 4], 
[6, 2, 4, 1, 9, 5, 7, 3, 0], 
[0, 9, 8, 0, 0, 0, 0, 6, 0],
[8, 0, 0, 0, 6, 0, 0, 0, 3],
[4, 0, 0, 8, 0, 3, 0, 0, 1], 
[7, 0, 0, 0, 2, 0, 0, 0, 6],
[0, 6, 0, 0, 0, 0, 2, 8, 0], 
[0, 0, 0, 4, 1, 9, 0, 0, 5], 
[0, 0, 0, 0, 8, 0, 0, 7, 9]

CodePudding user response:

The find_zero method returns a tuple of length 2. A non-zero length tuple will always evaluate to True, irrespective of its contents, so the conditional at the start of the solve method can never return True.

Thus your code will never recognise a valid solution. You should return None or False from find_zero if it doesn't find any.

CodePudding user response:

In addition to the problem Conor pointed out. There also is the problem that board is mutable and you change the board in potentially invalid ways that need to be rolled back. If you make a deepcopy of it every time you pass it to solve it works. Since I only changed the solve method I will post just that:

import copy

def solve(board):
    if find_zero(board)[0] is None:
        for row in board:
            print(row)
        return True
    else:
        row, col = find_zero(board)

    for value in range(1, 10):
        if is_valid(board, row, col, value):
            new_board = copy.deepcopy(board) 
            new_board[row][col] = value
            if solve(new_board):
                return True
    return False

In the end you get

[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]
True
  • Related