# 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