Skip to content

Commit fa356d4

Browse files
authored
Create Sudoku Solver.py
1 parent 3bc21f1 commit fa356d4

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

SudokuSolver/Sudoku Solver.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
class Mul():
2+
def combine(self, A, B):
3+
"Combines the elements of two given arrays."
4+
return [a + b for a in A for b in B]
5+
6+
7+
class SudokuSolver(Mul):
8+
9+
def __init__(self, grid=''):
10+
self.numbers = '123456789'
11+
self.characters = 'ABCDEFGHI'
12+
self.cols = self.numbers
13+
comb = Mul()
14+
self.squares = comb.combine(self.characters, self.cols)
15+
16+
self.Total = ([comb.combine(self.characters, c) for c in self.cols] +
17+
[comb.combine(r, self.cols) for r in self.characters] +
18+
[comb.combine(rs, cs) for rs in ('ABC', 'DEF', 'GHI') for cs in ('123', '456', '789')])
19+
20+
self.belongs = dict((s, [u for u in self.Total if s in u])
21+
for s in self.squares)
22+
23+
self.peers = dict((s, set(sum(self.belongs[s], [])) - set([s]))
24+
for s in self.squares)
25+
26+
def possible_values(self, grid):
27+
"Lists all the possible values for a particular cell."
28+
29+
values = dict((s, self.numbers) for s in self.squares)
30+
for s, d in self.StrToDict(grid).items():
31+
if d in self.numbers and not self.update(values, s, d):
32+
return False
33+
return values
34+
35+
def StrToDict(self, grid):
36+
"Converts the given string of sudoku values into dictionary."
37+
values = [c for c in grid if c in self.numbers or c in '0.']
38+
assert len(values) == 81
39+
return dict(zip(self.squares, values))
40+
41+
def update(self, values, s, d):
42+
"Keeps updating the values by elimination of other values."
43+
other_values = values[s].replace(d, '')
44+
if all(self.remove(values, s, d2) for d2 in other_values):
45+
return values
46+
else:
47+
return False
48+
49+
def remove(self, values, s, d):
50+
"""Eliminate d from values[s]; propagate when values or places <= 2.
51+
Return values, except return False if a contradiction is detected."""
52+
if d not in values[s]:
53+
return values
54+
values[s] = values[s].replace(d, '')
55+
56+
if len(values[s]) == 0:
57+
return False
58+
elif len(values[s]) == 1:
59+
d2 = values[s]
60+
if not all(self.remove(values, s2, d2) for s2 in self.peers[s]):
61+
return False
62+
63+
for u in self.belongs[s]:
64+
dplaces = [s for s in u if d in values[s]]
65+
if len(dplaces) == 0:
66+
return False
67+
elif len(dplaces) == 1:
68+
69+
if not self.update(values, dplaces[0], d):
70+
return False
71+
return values
72+
73+
def solve(self, grid):
74+
return self.depth_first(self.possible_values(grid))
75+
76+
def depth_first(self, values):
77+
"Using depth-first search and propagation, try all possible values."
78+
if values is False:
79+
return False
80+
81+
if all(len(values[s]) == 1 for s in self.squares):
82+
return values
83+
84+
n, s = min((len(values[s]), s) for s in self.squares if len(values[s]) > 1)
85+
return self.selected(self.depth_first(self.update(values.copy(), s, d))
86+
for d in values[s])
87+
88+
def selected(self, seq):
89+
"Return some element of seq that is true."
90+
for e in seq:
91+
if e: return e
92+
return False
93+
94+

0 commit comments

Comments
 (0)