def main(): # List of puzzles to solve puzzle_files = ["puzzle.txt", "puzzle2.txt", "puzzle3.txt", "puzzle4.txt"] print("Loading puzzles.") puzzles = [SudokuSolver.empty_puzzle()] for path in puzzle_files: try: puzzle = SudokuSolver.fromfile(path) except (NoSolutionFound, FileNotFoundError) as e: print(e) else: puzzles.append(puzzle) print("Puzzles loaded.\n") print("Starting to solve puzzles:") solver = SudokuSolver() for puzzle in puzzles: solver.puzzle = puzzle print("Trying to solve this sudoku puzzle:") print(solver.puzzle) try: solver.solve() except NoSolutionFound: print("There is no solution for this puzzle!") else: print("Solution found!") print(solver.solution)
def generate_sudoku(): sudoku_solver = SudokuSolver() array = [[0 for i in range(9)] for j in range(9)] rand_entry = randint(1, 9) rand_row, rand_col = (randint(0, 8), randint(0, 8)) array[rand_row][rand_col] = rand_entry sudoku_solver.solve(array) values_to_remove = sample([(j, k) for j in range(0, 9) for k in range(0, 9)], 48) for el in values_to_remove: array[el[0]][el[1]] = 0 solvable_array = deepcopy(array) if not sudoku_solver.solve(solvable_array): break return array
def test_multiple_solutions(): board = [ ["", "4", "", "1"], ["1", "", "4", ""], ["", "1", "", "4"], ["4", "", "1", ""], ] solutions = [ [ ["3", "4", "2", "1"], ["1", "2", "4", "3"], ["2", "1", "3", "4"], ["4", "3", "1", "2"], ], [ ["2", "4", "3", "1"], ["1", "3", "4", "2"], ["3", "1", "2", "4"], ["4", "2", "1", "3"], ], ] sudoku = SudokuSolver(board=board) sudoku_solutions = [_ for _ in sudoku.solve_all()] assert len(solutions) == 2 assert [s.board for s in sudoku_solutions] == solutions assert sudoku.solve().board == solutions[0]
def test_solver(): board = [ ["9", "", "", "", "", "8", "", "7", ""], ["5", "", "", "6", "7", "9", "2", "3", ""], ["1", "", "", "", "", "5", "9", "6", ""], ["8", "5", "", "7", "", "2", "6", "", ""], ["", "", "9", "8", "", "", "7", "", "2"], ["3", "7", "", "1", "", "", "", "", ""], ["", "", "4", "", "3", "", "5", "8", "6"], ["", "8", "3", "", "6", "", "", "", "4"], ["", "1", "5", "", "8", "", "", "", ""], ] solution = [ ["9", "2", "6", "3", "1", "8", "4", "7", "5"], ["5", "4", "8", "6", "7", "9", "2", "3", "1"], ["1", "3", "7", "4", "2", "5", "9", "6", "8"], ["8", "5", "1", "7", "9", "2", "6", "4", "3"], ["4", "6", "9", "8", "5", "3", "7", "1", "2"], ["3", "7", "2", "1", "4", "6", "8", "5", "9"], ["7", "9", "4", "2", "3", "1", "5", "8", "6"], ["2", "8", "3", "5", "6", "7", "1", "9", "4"], ["6", "1", "5", "9", "8", "4", "3", "2", "7"], ] sudoku = SudokuSolver(board=board) solutions = [_ for _ in sudoku.solve_all()] assert len(solutions) == 1 assert solutions[0].board == solution assert sudoku.solve().board == solution
def solve_puzzle(puzzle_strings): puzzle_id = puzzle_strings[0] solve_set = set() puzzle = Puzzle(puzzle_strings[1][0], solve_set) solution = Puzzle(puzzle_strings[1][1]) solver = SudokuSolver(puzzle, solve_set) solver.solve() if solver.puzzle == solution: print("Puzzle", puzzle_id, "Complete!") return 1 else: print("Bad Solution for", puzzle_id) return 0
class SudokuArSolver: MAX_IMG_SIZE = 400 def __init__(self): self.grid_detector = GridDetector() self.warper = ImageWarper() self.sudoku_solver = SudokuSolver(9) self.digit_reader = DigitReader() def solve(self, image): image = self.scale_too_big_image(image) grid_corners = self.grid_detector.find_grid(image, show_img=True) if grid_corners is None: return image warp = self.warper.warp(self.grid_detector.thresh_image, grid_corners) table = self.digit_reader.read_numbers(warp) self.sudoku_solver.print_grid(table) solved_table = self.sudoku_solver.solve(copy.deepcopy(table)) image_with_numbers = self.warper.write_number_to_image( warp, table, solved_table) res = self.warper.draw_warp_to_original(image_with_numbers, image) return res @staticmethod def scale_too_big_image(image): mx_size = np.max(image.shape) if mx_size > SudokuArSolver.MAX_IMG_SIZE: scale = mx_size / SudokuArSolver.MAX_IMG_SIZE return cv2.resize( image, (int(image.shape[1] / scale), int(image.shape[0] / scale))) return image def load_pic(self, path): image = cv2.imread(path) res = self.solve(image) cv2.imshow('frame', res) cv2.waitKey() def start_camera(self): cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() # frame = frame[60:-60, 60:-60] frame = frame[60:60 + 360, 180:180 + 360] res = self.solve(frame) cv2.imshow('Video', res) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
class TestSudoku(unittest.TestCase): def setUp(self): self.board = [[0, 0, 0, 2, 6, 0, 7, 0, 1], [6, 8, 0, 0, 7, 0, 0, 9, 0], [1, 9, 0, 0, 0, 4, 5, 0, 0], [8, 2, 0, 1, 0, 0, 0, 4, 0], [3, 0, 4, 6, 0, 2, 9, 0, 0], [0, 5, 0, 0, 0, 3, 0, 2, 8], [0, 0, 9, 3, 0, 0, 0, 7, 4], [0, 4, 0, 0, 5, 0, 0, 3, 6], [7, 0, 3, 0, 1, 8, 0, 0, 0]] self.solver = SudokuSolver(self.board) self.solver.solve() self.result = [i for i in range(1, 10)] def test_row(self): """ Checks if every row contains value from 1 to 9 or not. Also checks if there are any duplicate items or not. """ for i in range(len(self.solver.board[0])): self.assertListEqual(sorted(self.solver.board[i]), self.result) def test_column(self): """ Checks if every column contains value from 1 to 9 or not. Also checks if there are any duplicate items or not. """ for i in range(len(self.solver.board[0])): res = [self.solver.board[j][i] for j in range(9)] self.assertListEqual(sorted(res), self.result) def test_box(self): """ Checks if every 3*3 box contains value from 1 to 9 or not. Also checks if there are any duplicate items or not. """ for row in range(3): for col in range(3): start_x = row * 3 start_y = col * 3 vals = [self.solver.board[row][col] for col in range( start_y, start_y+3) for row in range(start_x, start_x+3)] self.assertListEqual(sorted(vals), self.result)
def test_incorrect_board(): board = [ ["1", "1", "1", "1"], ["", "", "", "4"], ["4", "", "3", "1"], ["3", "2", "4", ""], ] sudoku = SudokuSolver(board=board) solution = [_ for _ in sudoku.solve_all()] assert len(solution) == 0 assert sudoku.solve() is None
def solve_puzzle(): cells = [[0 for _ in range(9)] for _ in range(9)] for i in range(9): for j in range(9): if request.args[str(i) + str(j)]: cells[i][j] = int(request.args[str(i) + str(j)]) solver = SudokuSolver(cells) result, grid, path = solver.solve() return render_template('index.html', solution=True, result=result, content=path)
def test_simple_solver(): board = [ ["1", "", "2", "3"], ["2", "", "1", "4"], ["4", "", "3", "1"], ["3", "", "4", ""], ] solution = [list("1423"), list("2314"), list("4231"), list("3142")] sudoku = SudokuSolver(board=board) solutions = [_ for _ in sudoku.solve_all()] assert len(solutions) == 1 assert solutions[0].board == solution assert sudoku.solve().board == solution
def test_non_unique_solver(): # just test that this completes for a non unique board board = [ ["1", "", "", "", "", "", "", "", ""], ["", "2", "", "", "", "", "", "", ""], ["", "", "3", "", "", "", "", "", ""], ["", "", "", "", "", "", "", "", ""], ["", "", "", "", "", "", "", "", ""], ["", "", "", "", "", "", "", "", ""], ["", "", "", "", "", "", "", "", ""], ["", "", "", "", "", "", "", "", ""], ["", "", "", "", "", "", "", "", ""], ] sudoku = SudokuSolver(board=board) solution = sudoku.solve() assert all(r != "" for row in solution.board for r in row)
class SudokuGUI: def __init__(self, parent): self.ncells = 9 self.margin = 10 self.pixel_width = 500 self.canvas = Canvas(parent, width = self.pixel_width + 2 * self.margin, height = self.pixel_width + 2 * self.margin) self.canvas.bind("<Button-1>", self.change_cell) self.canvas.pack() self.button_solve = Button(parent, text = "Solve it!") self.button_solve.configure(command = self.solve) self.button_solve.pack() self.button_save = Button(parent, text = "Print") self.button_save.configure(command = self.save) self.button_save.pack() self.board = [[-1]*self.ncells for x in xrange(self.ncells)] self.solver = SudokuSolver() def save(self): out = 'sudoku.ps' tkMessageBox.showinfo("Print", "Printed solution to file %s"%out) self.canvas.postscript(file = 'sudoku.ps', colormode = 'color') def get_value(self, x): if x == -1: return ' ' return str(x) def solve(self): ok, ans = self.solver.solve(self.board) if not ok: tkMessageBox.showerror("FAIL", "Sudoku cannot be solved") return self.canvas.delete('all') for i in xrange(self.ncells): for j in xrange(self.ncells): if self.board[i][j] != ans[i][j]: self.draw_cell(i, j, self.get_value(ans[i][j]), color='blue') else: self.draw_cell(i, j, self.get_value(self.board[i][j]), color = 'black') print self.board def _get_next_value(self, snum): if snum == ' ': return '1' num = int(snum) num = (num + 1)%10 if num == 0: return ' ' else: return str(num) def update_text(self, e): value = self._get_next_value(self.canvas.itemcget(e, 'text')) self.canvas.itemconfigure(e, text = value) x, y = self.canvas.gettags(e)[1].split(' ') x, y = int(x), int(y) if value == ' ': self.board[x][y] = -1 else: self.board[x][y] = int(value) def change_cell(self, event): e = self.canvas.find_closest(event.x, event.y) if 'text' in self.canvas.gettags(e): self.update_text(e) else: if 'rectangle' in self.canvas.gettags(e): text_tag = self.canvas.gettags(e)[1] for x in self.canvas.find_withtag(text_tag): if 'text' in self.canvas.gettags(x): self.update_text(x) def draw_cell(self, i, j, value = ' ', color = 'black'): cellsize = self.pixel_width/self.ncells x1 = self.margin + i * cellsize y1 = self.margin + j * cellsize x2 = x1 + cellsize y2 = y1 + cellsize r_index = self.canvas.create_rectangle(x1, y1, x2, y2) t_index = self.canvas.create_text((x1 + x2)/2, (y1 + y2)/2, text=value, font = ('Helvectica', 30), fill = color) self.canvas.addtag_withtag('rectangle', r_index) self.canvas.addtag_withtag('%d %d'%(i, j), r_index) self.canvas.addtag_withtag('text', t_index) self.canvas.addtag_withtag('%d %d'%(i, j), t_index) if i % 3 == 0 and i > 0: self.canvas.create_line(x1, y1, x1, y1 + cellsize , width = 3) if j % 3 == 0 and j > 0: self.canvas.create_line(x1, y1, x1 + cellsize , y1, width = 3) def draw_board(self): for i in xrange(self.ncells): for j in xrange(self.ncells): if self.board[i][j] == -1: self.draw_cell(i, j) else: self.draw_cell(i, j, value = str(self.board[i][j]))
def testEvil(self): solver = SudokuSolver() solver.solve('../evilpuzzle.in') result = solver.printBoard() assert 'x' not in result, result +'\n' + solver.printTilePossibleValues() pass
def testHard(self): solver = SudokuSolver() solver.solve('../hardpuzzle.in') result = solver.printBoard() assert 'x' not in result, result pass
def getBoardInput(): board = [] for i in range(1, 10): rowValues = input(f'Enter entries for row number {i}: ') try: int(rowValues) except ValueError: print('Input values not valid') return None if len(str(rowValues)) != 9: print('You need to enter 9 values for each row') return None rowList = [int(i) for i in str(rowValues)] board.append(rowList) return board print(f'############## Sudoku Solver ##############') print(f'Program that solves a 9x9 Sudoku, let\'s go!\n') initialBoard = getBoardInput() if initialBoard is not None: sudokuSolver = SudokuSolver(initialBoard) if sudokuSolver.solve(): print('#####################') sudokuSolver.showBoard() print('#####################') else: print('The sudoku could not be solved')
def solve(row_list): rows = [map(int, list(row)) for row in row_list] solver = SudokuSolver() result = solver.solve(rows) output(result)
def __solve_puzzle(self): solver = SudokuSolver(self.game.puzzle) solver.solve() self.__draw_puzzle()
from sudoku_solver import SudokuSolver from utils import printBoard if __name__ == '__main__': ssolver = SudokuSolver() board = [[5, 3, 0, 0, 7, 0, 0, 0, 0], [6, 0, 0, 1, 9, 5, 0, 0, 0], [0, 9, 8, 0, 0, 0, 0, 6, 0], [8, 0, 0, 0, 6, 0, 0, 0, 3], [4, 0, 0, 8, 0, 3, 0, 0, 1], [7, 0, 0, 0, 2, 0, 0, 0, 6], [0, 6, 0, 0, 0, 0, 2, 8, 0], [0, 0, 0, 4, 1, 9, 0, 0, 5], [0, 0, 0, 0, 8, 0, 0, 0, 0]] print("puzzle:") printBoard(board) print() solutions = ssolver.solve(board, all=True) for solution in solutions: print("solution:") printBoard(solution) print()