# Lars.Rasmusson@gmail.com 2011-12-18
class sudoku(dict):
def __init__(self,game):
game = [g for g in game if g in ".123456789"]
for r in range(1,10):
for c in range(1,10):
self[(r,c)] = set(range(1,10)) if game[0] == '.' \
else set([int(game[0])])
game = game[1:]
def row(self, r): return [(r,c) for c in range(1,10)]
def col(self, c): return [(r,c) for r in range(1,10)]
def field(self, f):
fs = []
for x in range(1,10):
r = (x - 1) // 3 + 3 * ((f - 1) // 3) + 1
c = (x - 1) % 3 + 3 * ((f - 1) % 3) + 1
fs.append((r,c))
return fs
def different(self, vars, n):
from itertools import combinations
modified = False
for vs in combinations(vars, n):
u = set().union(*[self[x] for x in vs])
o = set().union(*[self[x] for x in vars if not x in vs])
if len(u) == n and o.intersection(u) != set():
for v in set(vars)-set(vs):
if self[v].intersection(u):
self[v] -= u
modified = True
return modified
def solve(self):
n = 1
while n < 9:
mod = False
for i in range(1,10):
mod |= self.different(self.row(i),n)
mod |= self.different(self.col(i),n)
mod |= self.different(self.field(i),n)
n = 1 if mod else n + 1
def write(self):
for r in range(1,10):
for c in range(1,10):
v = self[(r,c)]
print '.' if len(v) > 1 else list(v)[0],
print
def backtrack(self):
from copy import deepcopy
self.solve()
choices = [len(self[var]) for var in self]
if min(choices) < 1: return None
if max(choices) == 1: return self
var = [var for var in self if len(self[var]) > 1][0]
for val in self[var]:
s = deepcopy(self)
s[var] = set([val])
s = s.backtrack()
if s != None: return s
return None
def check(self):
for i in range(1,10):
s1 = set().union(*[self[v] for v in self.row(i)])
s2 = set().union(*[self[v] for v in self.col(i)])
s3 = set().union(*[self[v] for v in self.field(i)])
if not s1 == s2 == s3 == set(range(1,10)):
return False
return True
games = ["""
798 ... 2..
... 69. .73
.6. 27. 1..
6.. 94. .81
4.5 .61 .2.
9.2 8.. .3.
2.7 ... 4..
1.. 4.3 76.
..6 .19 .5.
"""
,
"""
... .4. ...
..5 ... .46
..7 ... ..5
.5. 3.. 2..
23. ... 97.
7.. 8.. ...
.9. .8. 3..
... .24 ...
12. .3. .8.
"""
,
"""
5.. 17. .39
..7 9.. ...
.1. ... 4..
... 8.2 7..
3.8 ... 6.2
..5 4.6 ...
..2 ... .5.
... ..5 9..
15. .29 ..7
"""
,
"""
.2. ..6 ..3
.7. 95. ...
..8 ... ...
..5 ... ...
... 248 .1.
.6. ..3 ..2
39. ... ...
... 1.. 79.
... ... 1..
"""
,
"""
... 76. .5.
..2 ... .9.
... .5. 7..
..4 ..1 ...
.3. ..8 57.
... 2.. 6..
42. .3. ...
7.. 8.. ...
... ... ..1
"""
,
"""
.6. .4. ...
8.. ... ..9
..7 ... 15.
... ..8 ...
..3 .9. 7.4
... ... .6.
.1. 6.. ..3
9.. 1.. 8..
62. ..5 ...
"""
,
"""
5.1 ..8 ...
... .4. .3.
... ... 15.
.6. 49. ...
... 6.. 9.7
..3 1.. ...
... ... .42
.4. 8.7 ...
.27 ... .6.
"""
,
"""
. . 2 | 4 . . | . 8 9
. 4 . | . . 8 | 2 7 .
. . . | . . 6 | . . 4
------|-------|------
. 7 . | 9 . . | . . .
. . . | . . . | . . .
3 . 8 | 5 . . | . . .
------|-------|------
. 9 7 | 3 . 1 | . 6 5
. 8 . | 7 2 . | . . .
4 . . | . . . | . . 8
""",
"""
. 4 3 | 9 8 . | 2 5 .
6 . . | 4 2 5 | . . .
2 . . | . . 1 | . 9 4
------|--------|------
9 . . | . . 4 | . 7 .
3 . . | 6 . 8 | . . .
4 1 . | 2 . 9 | . . 3
------|--------|------
8 2 . | 5 . . | . . .
. . . | . 4 . | . . 5
5 3 4 | 8 9 . | 7 1 .
"""
,
"""
1..4....8
...89.5..
.2...5...
..8....37
.9..5..2.
36....1..
...1...7.
..6.48...
9....3..4
"""
,
"""
.6. .4. ...
8.. ... ..9
..7 ... 15.
... ..8 ...
..3 .9. 7.4
... ... .6.
.1. 6.. ..3
9.. 1.. 8..
62. ..5 ...
"""
]
if __name__ == "__main__":
for game in games:
s = sudoku(game)
s.write()
# s.solve()
s = s.backtrack()
if s:
if s.check():
s.write()
else:
print "FAILED CHECK!"
else:
print None
print
söndag 18 december 2011
Python sudoku
Prenumerera på:
Kommentarer till inlägget (Atom)
Inga kommentarer:
Skicka en kommentar