Python for Sudoku: choose the tightest blank. The complete example includes small checks you can run; the full notes state its scope.
Show the complete Python solution
def solve_sudoku(board):
digits = set(range(1,10))
rows, cols, boxes = [set() for _ in range(9)], [set() for _ in range(9)], [set() for _ in range(9)]
blanks = []
for r in range(9):
for c in range(9):
value = board[r][c]
box = (r//3)*3+c//3
if value == 0: blanks.append((r,c))
elif value not in digits or value in rows[r] or value in cols[c] or value in boxes[box]:
return False
else: rows[r].add(value); cols[c].add(value); boxes[box].add(value)
def search():
if not blanks: return True
best = min(range(len(blanks)), key=lambda i: len(digits-rows[blanks[i][0]]-cols[blanks[i][1]]-boxes[(blanks[i][0]//3)*3+blanks[i][1]//3]))
r, c = blanks.pop(best); box = (r//3)*3+c//3
for value in sorted(digits-rows[r]-cols[c]-boxes[box]):
board[r][c] = value; rows[r].add(value); cols[c].add(value); boxes[box].add(value)
if search(): return True
rows[r].remove(value); cols[c].remove(value); boxes[box].remove(value)
board[r][c] = 0; blanks.insert(best,(r,c))
return False
return search()
puzzle = [[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]]
assert solve_sudoku(puzzle)
assert all(set(row) == set(range(1,10)) for row in puzzle)