Reputation: 1501
I'm trying to write a simple python Sudoku solver that's implement backtracking which seems to not work at all and doesn't solve anything which I don't Know why. The Puzzle is supposed to have a solution I guess the problem is from the backtracking mechanism but I'm not sure at all Why such behavior could occur.
matric =[
[7,8,0,4,0,0,1,2,0],
[6,0,0,0,7,5,0,0,9],
[0,0,0,6,0,1,0,7,8],
[0,0,7,0,4,0,2,6,0],
[0,0,1,0,5,0,9,3,0],
[9,0,4,0,6,0,0,0,5],
[0,7,0,3,0,0,0,1,2],
[1,2,0,0,0,7,4,0,0],
[0,4,9,2,0,6,0,0,7]
]
def is_possible(y: int, x: int, n: int) -> bool:
# check row and column
for i in range(9):
if matric[y][i] == n:
return False
for i in range(9):
if matric[i][x] == n:
return False
# check box
new_x = x // 3 * 3
new_y = y // 3 * 3
for i in range(3):
for j in range(3):
if matric[new_y + i][new_x + j] == n:
return False
return True
def solve():
global matric
# Find a point
for y in range(9):
for x in range(9):
if matric[y][x] == 0: # found a point to solve
for n in range(1, 10): # Check numbers
if is_possible(y, x, n):
matric[y][x] = n
solve() # Solve Next Point
matric[y][x] = 0 # Back track
return
solve()
for x in matric:
print(x)
Upvotes: 0
Views: 526
Reputation: 350212
Your code always backtracks, even when it has found a solution. There is nothing in your code that says "hey, I found a solution, let's stop looking further". So after all possibilities have been scanned, you end up with a complete backtracked matrix. There is nothing else that this code can do: it will backtrack and set everything to zero. There is no if solved: announce the solution
Let solve
return a boolean: when it finds that the matrix is full, it should return True
. If a recursive call returns True
, then don't clear any cell! Instead, immediately return True
. That way you will quickly backtrack out of the recursion tree, without changing anything in the matrix. The original caller will then find the matrix with the solution still in tact.
So:
def solve():
global matric
for y in range(9):
for x in range(9):
if matric[y][x] == 0:
for n in range(1, 10):
if is_possible(y, x, n):
matric[y][x] = n
if solve(): # Did we find a solution?
return True # Yes! Tell the caller!
matric[y][x] = 0 # Back track
return False # No way to fill this cell with a valid value
return True # Found no free cell, so this is a solved puzzle!
Be aware that although this algorithm may solve some puzzles, it will spend too much time on harder puzzles. To solve harder puzzles, you would need to add and maintain some more data structures to know which values can still be used in a cell, and which values still need to find a spot in a row, a column, or a block. This will give faster results than when you have to validate a placed value like you do now in is_possible
.
Upvotes: 2