-
Notifications
You must be signed in to change notification settings - Fork 0
/
sudoku_solver.py
84 lines (71 loc) · 3.02 KB
/
sudoku_solver.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
from collections import defaultdict
# http://www.websudoku.com/?level=1&set_id=9584958293
puzzle = [[0, 5, 0, 0, 0, 4, 0, 3, 9],
[7, 4, 0, 6, 0, 0, 0, 0, 0],
[0, 0, 3, 0, 0, 0, 0, 0, 7],
[3, 0, 5, 7, 4, 0, 8, 9, 0],
[0, 9, 0, 3, 2, 1, 0, 5, 0],
[0, 7, 6, 0, 8, 9, 3, 0, 4],
[9, 0, 0, 0, 0, 0, 4, 0, 0],
[0, 0, 0, 0, 0, 3, 0, 6, 8],
[4, 3, 0, 2, 0, 0, 0, 1, 0]]
def fetch_section_values(row_set, col_set):
"""
this code is redundant, but I'm not sure how to pull it out of where it currently lies below.
Purhaps a new approach to the problem would simplify the solution
"""
new_section = []
for row, col in zip([i for i in range(row_set, 3 + row_set) for _ in range(3)],
[i for i in range(col_set, 3 + col_set)] * 3):
value = puzzle[row][col]
if value != 0:
new_section.append(value)
return new_section
def solve_sudoku(puzzle):
section_values = defaultdict(list)
solve_list = []
# set initial section values and set the solve_list (every row, column position needing resolution)
for row_set in range(0, 7, 3):
for col_set in range(0, 7, 3):
for row, col in zip([i for i in range(row_set, 3 + row_set) for _ in range(3)],
[i for i in range(col_set, 3 + col_set)]*3):
value = puzzle[row][col]
if value != 0:
section_values[(row_set, col_set)].append(puzzle[row][col])
else:
solve_list.append({'row': row, 'col': col, 'sec': (row_set, col_set)})
entry = 0
first_guess = True
while len(solve_list) != entry:
rows = puzzle
columns = list(zip(*puzzle))
row = solve_list[entry]['row']
col = solve_list[entry]['col']
if first_guess:
row_values = set(rows[row])
col_values = set(columns[col])
sec_values = set(section_values[solve_list[entry]['sec']])
possible_values = set(range(1, 10)) - (row_values | col_values | sec_values)
if possible_values:
solve_list[entry]['possible_values'] = possible_values
else:
entry -= 1
first_guess = False
continue
# this is if first_guess == false and entry has ran out of possible values
if solve_list[entry]['possible_values']:
solve_list[entry]['current_value'] = solve_list[entry]['possible_values'].pop()
else:
puzzle[row][col] = 0
section_values[solve_list[entry]['sec']] = fetch_section_values(*solve_list[entry]['sec'])
entry -= 1
first_guess = False
continue
puzzle[row][col] = solve_list[entry]['current_value']
section_values[solve_list[entry]['sec']] = fetch_section_values(*solve_list[entry]['sec'])
first_guess = True
entry += 1
return puzzle
results = solve_sudoku(puzzle)
for i in results:
print(i)