sudoku_solver.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. class Board:
  2. symbols = "123456789"
  3. blank = "."
  4. _board = ["." * 10 for i in range(9)]
  5. def set_initial(self, board: list):
  6. self._board = board.copy()
  7. def get_row(self, x):
  8. return self._board[x]
  9. def get_col(self, y):
  10. return "".join([r[y] for r in self._board])
  11. def get_block(self, x, y):
  12. row = x // 3
  13. col = y // 3
  14. return [r[col * 3 : (col + 1) * 3] for r in self._board[row * 3 : (row + 1) * 3]]
  15. def is_blank(self, x, y):
  16. return self._board[x][y] == self.blank
  17. def is_solved(self):
  18. return self.blank not in "".join(self._board)
  19. def set_cell(self, x, y, value):
  20. self._board[x] = self._board[x][:y] + value + self._board[x][y + 1 :]
  21. def get_possibilities(self, x, y):
  22. all_symbols = list(self.get_row(x) + self.get_col(y) + "".join(self.get_block(x, y)))
  23. return set(self.symbols).difference(all_symbols)
  24. def get_all_possibilities(self):
  25. return [[self.get_possibilities(i, j) for j in range(9)] for i in range(9)]
  26. def get_unique_cell(self):
  27. for i in range(9):
  28. for j in range(9):
  29. if self.is_blank(i, j) and len(self.get_possibilities(i, j)) == 1:
  30. return (i, j)
  31. return None
  32. def get_next_blank(self):
  33. for i in range(9):
  34. for j in range(9):
  35. if self.is_blank(i, j):
  36. return (i, j)
  37. def solve(self):
  38. while cell := self.get_unique_cell():
  39. x, y = cell
  40. value = self.get_possibilities(x, y).pop()
  41. # print(x, y)
  42. self.set_cell(x, y, value)
  43. if not self.is_solved():
  44. cell = self.get_next_blank()
  45. x, y = cell
  46. snapshot = self._board.copy()
  47. for value in self.get_possibilities(x, y):
  48. self.set_cell(x, y, value)
  49. self.solve()
  50. if self.is_solved():
  51. break
  52. self.set_initial(snapshot)
  53. return self._board