-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.py
126 lines (101 loc) · 3.46 KB
/
utils.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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
rows = 'ABCDEFGHI'
cols = '123456789'
boxes = [r + c for r in rows for c in cols]
history = {} # history must be declared here so that it exists in the assign_values scope
def assign_value(values, box, value):
"""You must use this function to update your values dictionary if you want to
try using the provided visualization tool. This function records each assignment
(in order) for later reconstruction.
Parameters
----------
values(dict)
a dictionary of the form {'box_name': '123456789', ...}
Returns
-------
dict
The values dictionary with the naked twins eliminated from peers
"""
# Don't waste memory appending actions that don't actually change any values
if values[box] == value:
return values
prev = values2grid(values)
values[box] = value
if len(value) == 1:
history[values2grid(values)] = (prev, (box, value))
return values
def cross(A, B):
"""Cross product of elements in A and elements in B """
return [x+y for x in A for y in B]
def values2grid(values):
"""Convert the dictionary board representation to as string
Parameters
----------
values(dict)
a dictionary of the form {'box_name': '123456789', ...}
Returns
-------
a string representing a sudoku grid.
Ex. '2.............62....1....7...6..8...3...9...7...6..4...4....8....52.............3'
"""
res = []
for r in rows:
for c in cols:
v = values[r + c]
res.append(v if len(v) == 1 else '.')
return ''.join(res)
def grid2values(grid):
"""Convert grid into a dict of {square: char} with '123456789' for empties.
Parameters
----------
grid(string)
a string representing a sudoku grid.
Ex. '2.............62....1....7...6..8...3...9...7...6..4...4....8....52.............3'
Returns
-------
A grid in dictionary form
Keys: The boxes, e.g., 'A1'
Values: The value in each box, e.g., '8'. If the box has no value,
then the value will be '123456789'.
"""
sudoku_grid = {}
for val, key in zip(grid, boxes):
if val == '.':
sudoku_grid[key] = '123456789'
else:
sudoku_grid[key] = val
return sudoku_grid
def display(values):
"""Display the values as a 2-D grid.
Parameters
----------
values(dict): The sudoku in dictionary form
"""
width = 1+max(len(values[s]) for s in boxes)
line = '+'.join(['-'*(width*3)]*3)
for r in rows:
print(''.join(values[r+c].center(width)+('|' if c in '36' else '')
for c in cols))
if r in 'CF': print(line)
print()
def reconstruct(values, history):
"""Returns the solution as a sequence of value assignments
Parameters
----------
values(dict)
a dictionary of the form {'box_name': '123456789', ...}
history(dict)
a dictionary of the form {key: (key, (box, value))} encoding a linked
list where each element points to the parent and identifies the value
assignment that connects from the parent to the current state
Returns
-------
list
a list of (box, value) assignments that can be applied in order to the
starting Sudoku puzzle to reach the solution
"""
path = []
prev = values2grid(values)
while prev in history:
prev, step = history[prev]
path.append(step)
return path[::-1]