I transcribed my Java Sudoku solver into python. Everything works, however solving takes up to 2mins, while the identical puzzle takes only a few seconds in Java. Also the iterations needed amount to the exact same number. Am I missing something?
import numpy as np
def solve_recursive(puzzle, pos):
if(pos == 81):
print puzzle
return True
if(puzzle[pos] != 0):
if (not solve_recursive(puzzle, pos+1)):
return False
else:
return True
row = np.copy(puzzle[pos//9*9:pos//9*9+9])
col = np.copy(puzzle[pos%9::9])
short = (pos%9)//3*3 + pos//27*27
square = np.concatenate((puzzle[short:short+3],puzzle[short+9:short+12],puzzle[short+18:short+21]))
for i in range(1,10):
puzzle[pos] = i
if(i not in row and i not in col and i not in square and solve_recursive(puzzle, pos+1)):
return True
puzzle[pos] = 0
return False
puzzle = np.array([[0,0,0,0,0,0,0,8,3],
[0,2,0,1,0,0,0,0,0],
[0,0,0,0,0,0,0,4,0],
[0,0,0,6,1,0,2,0,0],
[8,0,0,0,0,0,9,0,0],
[0,0,4,0,0,0,0,0,0],
[0,6,0,3,0,0,5,0,0],
[1,0,0,0,0,0,0,7,0],
[0,0,0,0,0,8,0,0,0]])
solve_recursive(puzzle.ravel(), 0)
EDIT:
As suggested by @hpaulj I reworked my code to work with numpy´s 2D arrays:
import numpy as np
def solve_recursive(puzzle, pos):
if pos == (0,9):
print puzzle
raise Exception("Solution")
if(puzzle[pos] != 0):
if(pos[0] == 8):
solve_recursive(puzzle, (0,pos[1]+1))
return
elif pos[0] < 8:
solve_recursive(puzzle, (pos[0]+1, pos[1]))
return
for i in range(1,10):
if(i not in puzzle[pos[0]] and i not in puzzle[:,pos[1]] and i not in puzzle[pos[0]//3*3:pos[0]//3*3+3,pos[1]//3*3:pos[1]//3*3+3]):
puzzle[pos] = i
if(pos[0] == 8):
solve_recursive(puzzle, (0,pos[1]+1))
elif pos[0] < 8:
solve_recursive(puzzle, (pos[0]+1, pos[1]))
puzzle[pos] = 0
puzzle = np.array([[0,0,0,0,0,0,0,8,3],
[0,2,0,1,0,0,0,0,0],
[0,0,0,0,0,0,0,4,0],
[0,0,0,6,1,0,2,0,0],
[8,0,0,0,0,0,9,0,0],
[0,0,4,0,0,0,0,0,0],
[0,6,0,3,0,0,5,0,0],
[1,0,0,0,0,0,0,7,0],
[0,0,0,0,0,8,0,0,0]])
solve_recursive(puzzle, (0,0))
Ignoring the fact that throwing an exception at the bottom of the recursive calls is rather inelegant, this is just inconsiderably faster than my original solution. Would using dictionaries like the linked Norvig solver be a reasonable alternative?