I have reviewed multiple questions regarding similar problems but have not been able to find a solution. I have to write a script for solving and displaying a sudoku puzzle in a text file. If there is no possible solution, it should return None, otherwise it should print the formatted and solved puzzle. My issue is that my solve() function always returns None, even for puzzles with simple solutions. I have tried to debug by following the logic and reviewing my syntax but I fear I am making a simple mistake I cannot see. My functions are
def load_puzzle(path):
with open(path) as fin:
contents = fin.read()
lines = contents.split('\n')
puzzle = []
for i in lines:
token_strings = i.split(' ')
token_ints = [int(x) for x in token_strings]
puzzle.append(token_ints)
return puzzle
def display_puzzle(puzzle):
for i in range(9):
if i == 0 or i == 3 or i == 6:
print('+-------+-------+-------+')
row = '| '
for j in range(9):
if puzzle[i][j] == 0:
row = row + '. '
else:
row = row + str(puzzle[i][j]) + ' '
if j==2 or j==5 or j==8:
row = row + '| '
print(row)
print('+-------+-------+-------+')
def get_next(row, col):
if col < 8:
#print('inside get_next') #DEBUG
return row, col+1
elif col == 8 and row < 8:
return row+1, 0
elif col == 8 and row == 8:
return None, None
def copy_puzzle(puzzle):
new_puzzle = []
for i in puzzle:
new_puzzle.append(i.copy())
return new_puzzle
def get_options(puzzle, row, col):
if puzzle[row][col] > 0:
return None
used = []
for i in puzzle[row]:
if i > 0:
used.append(i)
for i in range(9):
if puzzle[i][col] > 0:
used.append(puzzle[i][col])
start_row = 3*int(row/3)
start_col = 3*int(col/3)
for i in range(2):
for j in range(2):
if puzzle[start_row + i][start_col +j] > 0:
used.append(puzzle[start_row + i][start_col +j])
options = []
for i in range(1, 10):
if i not in used:
options.append(i)
return options
def solve(puzzle, row=0, col=0):
if puzzle[row][col] != 0:
#print("here") # debuggin
next_row, next_col = get_next(row, col)
#print(next_row, next_col) # debugging
if next_row is None:
return puzzle
else:
solve(puzzle, next_row, next_col)
if puzzle[row][col] == 0:
# print("there") # debuggin
options = get_options(puzzle, row, col)
#print(options) #debuggin
if options == []:
return None
for i in options:
new_puzzle = copy_puzzle(puzzle)
new_puzzle[row][col] = i
# display_puzzle(new_puzzle) #debuggin
result = solve(new_puzzle, row, col)
if result is not None:
return result
The commented out print() functions are ones I used to follow the loops to make sure the functions were operating as intended. As far as I can tell they were, but with so many loops, Jupyter Notebook began to print over itself and the display became indecipherable, as well as the making the function have an unreasonable resolution time.
The initial test puzzle is a .txt file containing:
5 0 0 0 0 0 0 0 0
0 9 0 7 0 0 8 0 0
0 0 0 0 3 0 0 7 0
6 0 1 0 0 0 9 8 0
0 0 0 6 0 0 0 0 0
0 0 9 0 0 0 7 0 1
0 0 0 0 0 8 1 9 0
0 4 0 5 0 1 0 0 8
0 7 0 3 0 6 0 4 0