import sys
sys.setrecursionlimit(1500) # the default recursion limit is 1000
def print_grid(arr):
for i in range(9):
for j in range(9):
print(arr[i][j])
print('\n')
def find_empty_location(arr, l):
for i in range(9):
for j in range(9):
if (arr[i][j] == 0):
l[0] = i
l[1] = j
return True
return False
def row_check(arr, row, num):
for x in range(9):
if arr[row][x] == num:
return True
return False
def col_check(arr, col, num):
for i in range(9):
if arr[i][col] == num:
return True
return False
def used_in_box(arr, row, col, num):
for i in range(3):
for j in range(3):
if (arr[i + row][j + col] == num):
return True
return False
def check_location_is_safe(arr, row, col, num):
return not row_check(arr, row, num) and not col_check(arr, col, num) and not used_in_box(arr, row - row % 3, col - col % 3, num)
def solve_sudoku(arr):
l = [0, 0]
if (not find_empty_location(arr, l)):
return True
row = l[0]
col = l[1]
for num in range(1, 10):
if check_location_is_safe(arr, row, col, num):
arr[row][col] == num
if solve_sudoku(arr):
return True
else:
arr[row][col] = 0
return False
if __name__ == "__main__":
grid = [[0 for x in range(9)] for y in range(9)]
grid = [[3, 0, 6, 5, 0, 8, 4, 0, 0],
[5, 2, 0, 0, 0, 0, 0, 0, 0],
[0, 8, 7, 0, 0, 0, 0, 3, 1],
[0, 0, 3, 0, 1, 0, 0, 8, 0],
[9, 0, 0, 8, 6, 3, 0, 0, 5],
[0, 5, 0, 0, 9, 0, 6, 0, 0],
[1, 3, 0, 0, 0, 0, 2, 5, 0],
[0, 0, 0, 0, 0, 0, 0, 7, 4],
[0, 0, 5, 2, 0, 6, 3, 0, 0]]
if (solve_sudoku(grid)):
print_grid(grid)
else:
print('NO SOLUTION EXISTS')

- 25,419
- 17
- 47
- 88

- 1
-
What errors? Please [edit] to post the full Traceback. – Gino Mempin Jan 11 '20 at 08:27
1 Answers
Before looking at the code, you should already realise that in a correct solution, the recursion depth should never have to be greater than the number of empty cells in the sudoku grid. So if recursion goes deeper than that, it should ring the bell that you actually have a bug that makes your code recurse infinitely. Increasing the recursion limit is the wrong reaction.
Instead you should debug and see what is actually happening. What I tend to do in such cases is add a depth=0
parameter to the recursive function (with default value 0). Then make sure the recursive call passes the value depth+1
. Add an if depth > 5: raise ValueError("stop")
in the function to make sure it does not run that often. Finally add some print
statements to inspect what your grid looks like, which row/col are selected, ...etc. You would soon detect something is going terribly wrong...
Now to the code: there are the following issues in your solve_sudoku
function:
arr[row][col] == num
is not an assignment, but a comparison. So you actually never change the grid.Even with the above correction, you still keep recursing without changing the grid when
check_location_is_safe
returnsFalse
. So the following lines should have been indented more, so they belong to theif
block above it:if solve_sudoku(arr): return True else: arr[row][col] = 0 # return False <--- not here (cf. previous issue)
NB: Since in the
if
case you exit the function, there is actually no real need to havearr[row][col] = 0
in anelse
. So it could well be:if solve_sudoku(arr): return True arr[row][col] = 0
return False
should not be inside thefor
loop, because you still want to verify alternative "moves" in next iterations of the loop.return False
should be executed after the loop has finished.
So taking those corrections together: the second half of solve_sudoku
should look like this:
for num in range(1, 10):
if check_location_is_safe(arr, row, col, num):
arr[row][col] = num
if solve_sudoku(arr):
return True
arr[row][col] = 0
return False

- 317,000
- 35
- 244
- 286