def basicCreate(self): su = sudoku.Sudoku(list()) empties = su.getEmptySquares() randomChoice = random.choice(empties) domain = su.getLegalMoves(randomChoice[0], randomChoice[1]) randomValue = random.choice(domain) su.setSquare(randomChoice[0], randomChoice[1], randomValue) self.feature.doRandomBacktracking(su, []) su = self.feature.backTrackingResult
def test_HiddenSinglesSolver(self): s = sdk.Sudoku() dlvl = 0 miter = 3 filename = GetPath('../sudokus/1') s.Load(filename) solver = sdk.HiddenSinglesSolver(s, miter, dlvl) solver.IterateOnce() s = solver.GetSudoku() self.assertEqual(s[5, 5].GetValue(), 8)
def test_Solver_init(self): s = sdk.Sudoku() dlvl = 0 miter = 20 filename = GetPath('../sudokus/1') s.Load(filename) solver = sdk.SinglesSolver(s, miter, dlvl) msg = str(solver) self.assertIn(str(miter), msg) self.assertIn(str(dlvl), msg)
def parse(self, filename): the_file = open(filename) pattern = "[0-9\.]" prog = re.compile(pattern) all_puzzles = list() current_puzzle = list() row = 0 for line in the_file: if row == 0: if "very easy" in line: current_puzzle.append("very easy") else: if "hard" in line: current_puzzle.append("hard") if "easy" in line: current_puzzle.append("easy") if "medium" in line: current_puzzle.append("medium") if "fiendish" in line: current_puzzle.append("fiendish") row += 1 continue if row == 4 or row == 8: row += 1 continue #Read in the current row to the row dict row_list = list() row_list = prog.findall(line) new_row = list() for box in row_list: if box == ".": new_row.append(0) else: new_row.append(int(box)) if len(row_list) != 9: print "ERROR ERROR ERROR" print line break #blah balh current_puzzle.append(new_row) if row == 11: row = 0 all_puzzles.append(current_puzzle) if len(current_puzzle) != 10: print current_puzzle print "ASFDLJASLFKJDSAs" current_puzzle = list() continue row += 1 print "Puzzles parsed:", len(all_puzzles) sudokus = list() for puzzle in all_puzzles: sudokus.append(sudoku.Sudoku(puzzle)) return sudokus
def single_puz(file_name): s = sudoku.Sudoku(file_name) print("initial state:\n" + str(s)) s.solve() if (s.is_solved()): print("puzzle solved!\n" + str(s)) elif (s.pq.last > 0): print( "implemented algorithms cannot solve this puzzle\nfinal state:\n" + str(s)) else: print("puzzle completed incorrectly:\n" + str(s))
def __init__(self): """ This function initializes the Sudoku env and creates a Sudoku grid. Args: - self: SudokuEnv, to be created. Returns: - None """ self.sudoku = sudoku.Sudoku() self.state = self.sudoku.grid self.episode_over = False self.reward = len(self.state[self.state > 0])
def test_naked_twins(values): """Eliminate values using the naked twins strategy. Args: values(dict): a dictionary of the form {'box_name': '123456789', ...} Returns: the values dictionary with the naked twins eliminated from peers. """ # Find all instances of naked twins sudoku = sdk.Sudoku(values, partial=True) sudoku.naked_twins() return sudoku.values
def test_SinglesSolver(self): s = sdk.Sudoku() dlvl = 0 miter = 3 filename = GetPath('../sudokus/1') correct = LoadSolution(filename) s.Load(filename) solver = sdk.SinglesSolver(s, miter, dlvl) solver.Execute() s = solver.GetSudoku() for r in range(1, 10): for c in range(1, 10): self.assertEqual(correct[r - 1][c - 1], s[r, c].GetValue())
def test_NakedSinglesSolver(self): s = sdk.Sudoku() dlvl = 0 miter = 3 filename = GetPath('../sudokus/1') s.Load(filename) solver = sdk.NakedSinglesSolver(s, miter, dlvl) solver.Execute() s = solver.GetSudoku() self.assertEqual( str(s), '7 2 3 · 4 · 1 5 9 \n6 1 · 3 9 2 4 7 8 \n8 · · · 1 5 6 3 2 \n\n3 7 · 6 5 4 9 2 1 \n1 9 4 2 8 7 3 6 5 \n2 5 6 9 3 1 8 4 7 \n\n5 6 1 4 7 9 2 8 3 \n4 8 7 1 2 3 5 9 6 \n9 3 2 5 6 8 7 1 4 \n' )
def solve(grid): """ Find the solution to a Sudoku grid. Args: grid(string): a string representing a sudoku grid. Example: '2.............62....1....7...6..8...3...9...7...6..4...4....8....52.............3' Returns: The dictionary representation of the final sudoku grid. False if no solution exists. """ diagonal_sudoku = sdk.Sudoku(grid, diag=True) diagonal_sudoku.search() diagonal_sudoku.display() return diagonal_sudoku.values
def get_sudoku_solution(): current_assignment = request.get_json() # remove pseudo assignments current_assignment = { square: value for square, value in current_assignment.items() if value != "0" } # load sudoku current_grid = sudoku.decode_assignment(current_assignment) current_sudoku = sudoku.Sudoku(grid=current_grid) # get solution solved_assignment, _ = current_sudoku.solve() return json.jsonify(solved_assignment)
def set_val(puzzle, all_vals, row, col): n = random.randint(0, len(all_vals)) orig = deepcopy(puzzle) # randomly chooses a number and checks if it can be used # if not checks next number in all_vals k = len(all_vals) for i in range(n, n + k): puzzle = deepcopy(orig) j = i % k try: puzzle[row][col] = all_vals[j] except: print("exception") continue s = sudoku.Sudoku(puzzle) s.solve() if s.is_solved(): puzzle = deepcopy(orig) puzzle[row][col] = all_vals[j] s = sudoku.Sudoku(puzzle) return puzzle puzzle = deepcopy(orig) puzzle[row][col] = 0 return puzzle
def test_BranchingSolver(self): filename = GetPath('../sudokus/3') dlvl = 0 miter = 12 config = sdk.SolverConfig("SinglesSolver", 10, 0) s = sdk.Sudoku() s.Load(filename) correct = LoadSolution(filename) solver = sdk.BranchingSolver(s, miter, dlvl, config) solver.Execute() s = solver.GetSudoku() for r in range(1, 10): for c in range(1, 10): self.assertEqual(correct[r - 1][c - 1], s[r, c].GetValue())
def index_post(): if "load" in request.form: s = image_to_sudoku(request.files.get("image")) if s: return redirect(f"/?table={sudoku.serialize(s)}&message=Loaded!") else: return redirect(f"/?message=Image loading failed :(") elif "backtrack" in request.form or "sat" in request.form: cells = [int(request.form["cell%d" % i] or 0) for i in range(81)] solver = sudoku.solve if "backtrack" in request.form else sudoku.solve_sat s = solver(sudoku.Sudoku(cells)) if s: return redirect(f"/?table={sudoku.serialize(s)}&message=Solved!") else: return redirect("/?message=Solving failed :(") elif "clear" in request.form: return redirect("/?message=Cleared!")
def count_puz(dir_name): files = glob.glob(dir_name + "/*.txt") total = len(files) correct = 0 incorrect = 0 unsolved = 0 for file_name in files: s = sudoku.Sudoku(file_name) s.solve() if (s.is_solved()): correct += 1 elif (s.pq.last > 0): unsolved += 1 else: incorrect += 1 print("num puzzles: " + str(total)) print("num correct: " + str(correct)) print("num incorrect: " + str(incorrect)) print("num unsolved: " + str(unsolved))
def main(): mySudoku = sudoku.Sudoku(9, 3, 'board.txt') print("Board to be solved: ") mySudoku.printMyBoard() print() prompt = input('Press (C)ontinue or (Q)uit... ') print() if not prompt.upper().startswith('C'): print("quitting...") print() sys.exit() print() start = time.time() if mySudoku.solveBoard(): print("solved!...") mySudoku.printMyBoard() end = time.time() total = end - start print("Total time to solve: %s seconds." % (total)) else: print("not solved...")
def test_sudoku_load(self): s0 = sdk.Sudoku() filename = GetPath('../sudokus/1') correct = LoadSudoku(filename) # Loading s0.Load(filename) # Testing copying s = s0.copy() for r in range(1, 10): for c in range(1, 10): cell = s[r, c] try: if cell.IsSolved(): self.assertEqual(correct[r - 1][c - 1], cell.GetValue()) else: self.assertEqual(correct[r - 1][c - 1], 0) except: raise AssertionError("Failure at r%dc%d" % cell.GetCoords())
def sudoku_testing(): total_time = 0 with open(sys.argv[1],'r') as tests: nb_test = 0 for sudoku in tests: nb_test += 1 sudoku = sudoku[:81] sudoku = [list(map(lambda x: 0 if x == '.' else int(x),sudoku[9*i:9*(i+1)])) for i in range(9)] checkpoint = time.time() s = sdk.Sudoku(sudoku, pprint=True) # print(s) # root = s.produce_dlx() # print('exploring column', root.right.idcol) # for x in root.right.cell.iter(start=root.right.cell.down): # print(x.idrow, ':', end=' ') # for y in x.iter(start=x.right, direction='right'): # print(y.colhead.idcol, end=' ') # print() s.solve(inplace=True) # print(s, '\n') total_time += time.time()-checkpoint return total_time / float(nb_test)
def generate_puzzle(): puzzle = [] # 9x9 2d array of 0s for i in range(9): puzzle.append([]) for j in range(9): puzzle[i].append(0) # generates a completely solved puzzle for i in range(9): for j in range(9): vals = get_vals(puzzle, i, j) puzzle = set_val(puzzle, vals, i, j) s = sudoku.Sudoku(puzzle) # randomly removes numbers from puzzle (by replaceing them with 0) for i in range(9): for j in range(9): n = random.randint(0, 10) if n <= 5: puzzle[i][j] = 0 return puzzle
def createSudoku(self, level): extraGenerated = 0 if len(self.stored[level]) == 0: foundPuzzle = False while(not foundPuzzle): su = sudoku.Sudoku(list()) empties = su.getEmptySquares() randomChoice = random.choice(empties) domain = su.getLegalMoves(randomChoice[0], randomChoice[1]) randomValue = random.choice(domain) su.setSquare(randomChoice[0], randomChoice[1], randomValue) self.feature.doRandomBacktracking(su, []) su = self.feature.backTrackingResult su.printSolution() if "easy" in level or "medium" in level: keep = random.randrange(30, 35) else: keep = random.randrange(17, 35) remove = 81 - keep for i in range(remove): nonempties = su.getNonEmptySquares() choice = random.choice(nonempties) su.clearSquare(choice[0], choice[1]) su_level = self.classify(su) su.setClassification(su_level) su.printPuzzle() if level == su.getDifficulty() or (level == "very easy" and su.getDifficulty() == "easy"): foundPuzzle = True else: extraGenerated += 1 self.stored[su.getDifficulty()].append(su) else: su = self.stored[level].pop() print "Extra puzzles generated:", extraGenerated return su
def test(): files = os.listdir("data/sorted") for file in sorted(files): with open("data/sorted/" + file, "r") as input: input.readline() print("FILENAME: " + file) results = [] i = 0 solved_by_ac = 0 t = sudoku.Sudoku(None) for line in input: #SETUP steps = [0, 0, 0, 0, 0, 0, 0, 0] (puzzle, solution) = line.split(",") s = sudoku.Sudoku(puzzle) #TEST EFFECTIVENESS OF AC vs DEFAULT BACKTRACKING p = s.to_problem() sudoku.Solver.counter = 0 if sudoku.Solver.AC_1(p): solved_by_ac += 1 else: if not sudoku.Solver.backtracking(p): raise Exception steps[1] = sudoku.Solver.counter sudoku.Solver.counter = 0 t.from_problem(p) if t.__repr__() != solution[:-1]: raise Exception p = s.to_problem() sudoku.Solver.backtracking(p) steps[0] = sudoku.Solver.counter sudoku.Solver.counter = 0 t.from_problem(p) if t.__repr__() != solution[:-1]: raise Exception #TEST FORWARD CHECKING p = s.to_problem() sudoku.Solver.forward_checking(p) steps[2] = sudoku.Solver.counter t.from_problem(p) if t.__repr__() != solution[:-1]: raise Exception #TEST FORWARD CHECKING WITH FIRST FAIL p = s.to_problem() sudoku.Solver.forward_checking(p, True) steps[3] = sudoku.Solver.counter t.from_problem(p) if t.__repr__() != solution[:-1]: raise Exception #TEST FORWARD CHECKING WITH MIN CONFLICT p = s.to_problem() sudoku.Solver.forward_checking(p, least_conflict_heuristic=True) steps[4] = sudoku.Solver.counter steps[5] = sudoku.Solver.aux_counter t.from_problem(p) if t.__repr__() != solution[:-1]: raise Exception # TEST FORWARD CHECKING WITH both p = s.to_problem() sudoku.Solver.forward_checking(p, True, True) steps[6] = sudoku.Solver.counter steps[7] = sudoku.Solver.aux_counter t.from_problem(p) if t.__repr__() != solution[:-1]: raise Exception #FINALIZE results.append(steps) i += 1 if i > 4999: break # with open("results/"+file, "w") as output: # output.write("BT,BT+AC,FC,FCFF,FCMC\n") # for r in results: # output.write(str(r)[1:-1]) # output.write("\n") print(f"Number of puzzles: {i}") print( f"Solved by AC only: {solved_by_ac} ({solved_by_ac/i*100:.2f}%)" ) backtracking = get_col(results, 0) withAC = get_col(results, 1) FC = get_col(results, 2) FCFF = get_col(results, 3) FCMC = get_col(results, 4) FCMCAUX = get_col(results, 5) FCB = get_col(results, 6) FCBAUX = get_col(results, 7) print( f"Backtraking: min {min(backtracking)}, avg {statistics.mean(backtracking):.2f}, max {max(backtracking)} values tested" ) print([ round(q, 1) for q in statistics.quantiles(backtracking, n=10) ]) print( f"Backtraking with AC: min {min(withAC)}, avg {statistics.mean(withAC):.2f}, max {max(withAC)} values tested" ) print([round(q, 1) for q in statistics.quantiles(withAC, n=10)]) print( f"Forward checking: min {min(FC)}, avg {statistics.mean(FC):.2f}, max {max(FC)} values tested" ) print([round(q, 1) for q in statistics.quantiles(FC, n=10)]) print( f"Forward checking with FF: min {min(FCFF)}, avg {statistics.mean(FCFF):.2f}, max {max(FCFF)} values tested" ) print([round(q, 1) for q in statistics.quantiles(FCFF, n=10)]) print( f"Forward checking with MC: min {min(FCMC)}, avg {statistics.mean(FCMC):.2f}, max {max(FCMC)} values tested" ) print([round(q, 1) for q in statistics.quantiles(FCMC, n=10)]) print( f"using the results of other: min {min(FCMCAUX)}, avg {statistics.mean(FCMCAUX):.2f}, max {max(FCMCAUX)} values tested" ) print([round(q, 1) for q in statistics.quantiles(FCMCAUX, n=10)]) print( f"Forward checking with both: min {min(FCB)}, avg {statistics.mean(FCB):.2f}, max {max(FCB)} values tested" ) print([round(q, 1) for q in statistics.quantiles(FCB, n=10)]) print( f"using the results of other: min {min(FCBAUX)}, avg {statistics.mean(FCBAUX):.2f}, max {max(FCBAUX)} values tested" ) print([round(q, 1) for q in statistics.quantiles(FCBAUX, n=10)]) print()
def test2(): results = [] with open("data/sorted/48.csv", "r") as input: input.readline() print("FILENAME: data/sorted/48.csv") i = 0 for line in input: # SETUP times = [0, 0, 0, 0, 0, 0, 0, 0] (puzzle, solution) = line.split(",") s = sudoku.Sudoku(puzzle) # TEST AC p = s.to_problem() start = time.process_time() if not sudoku.Solver.AC_1(p): if not sudoku.Solver.backtracking(p): raise Exception end = time.process_time() times[0] = end - start # DEFAULT BACKTRACKING p = s.to_problem() start = time.process_time() sudoku.Solver.backtracking(p) end = time.process_time() times[1] = end - start # TEST FORWARD CHECKING p = s.to_problem() start = time.process_time() sudoku.Solver.forward_checking(p) end = time.process_time() times[2] = end - start # TEST FORWARD CHECKING WITH FIRST FAIL p = s.to_problem() start = time.process_time() sudoku.Solver.forward_checking(p, True) end = time.process_time() times[3] = end - start # TEST FORWARD CHECKING WITH MIN CONFLICT p = s.to_problem() start = time.process_time() sudoku.Solver.forward_checking(p, least_conflict_heuristic=True) end = time.process_time() times[4] = end - start # TEST FORWARD CHECKING WITH both p = s.to_problem() start = time.process_time() sudoku.Solver.forward_checking(p, True, True) end = time.process_time() times[5] = end - start # FINALIZE results.append(times) i += 1 if i > 4999: break backtracking = get_col(results, 1) withAC = get_col(results, 0) FC = get_col(results, 2) FCFF = get_col(results, 3) FCMC = get_col(results, 4) FCB = get_col(results, 5) print( f"AC: min {min(withAC):.4f}, avg {statistics.mean(withAC):.4f}, max {max(withAC):.4f} values tested" ) print([round(q, 4) for q in statistics.quantiles(withAC, n=10)]) print(f"Sum: {sum(withAC):.2f}") print( f"Backtracking: min {min(backtracking):.4f}, avg {statistics.mean(backtracking):.4f}, max {max(backtracking):.4f} values tested" ) print([round(q, 4) for q in statistics.quantiles(backtracking, n=10)]) print(f"Sum: {sum(backtracking):.2f}") print( f"Forward checking: min {min(FC):.4f}, avg {statistics.mean(FC):.4f}, max {max(FC):.4f} values tested" ) print([round(q, 4) for q in statistics.quantiles(FC, n=10)]) print(f"Sum: {sum(FC):.2f}") print( f"Forward checking with FF: min {min(FCFF):.4f}, avg {statistics.mean(FCFF):.4f}, max {max(FCFF):.4f} values tested" ) print([round(q, 4) for q in statistics.quantiles(FCFF, n=10)]) print(f"Sum: {sum(FCFF):.2f}") print( f"Forward checking with MC: min {min(FCMC):.4f}, avg {statistics.mean(FCMC):.4f}, max {max(FCMC):.4f} values tested" ) print([round(q, 4) for q in statistics.quantiles(FCMC, n=10)]) print(f"Sum: {sum(FCMC):.2f}") print( f"Forward checking with both: min {min(FCB):.4f}, avg {statistics.mean(FCB):.4f}, max {max(FCB):.4f} values tested" ) print([round(q, 4) for q in statistics.quantiles(FCB, n=10)]) print(f"Sum: {sum(FCB):.2f}") print()
0, 8, 5, 0, 0, 0, 1, 0, 0, 9, 0, 0, 0, 0, 4, 0, 0, ]) for example in examples: print "EXAMPLE:" problem = sudoku.Sudoku(example) print problem.ascii solution = problem.solve() if solution: print "Solution:" print solution.ascii else: print "Invalid puzzle." print
def solve_sudoku_ocr(src, crossing_points): """ Split the rectified sudoku image into smaller pictures of letters only. Then perform ocr on the letter images, create and solve the sudoku using the Sudoku class. """ numbers = [] # enumerate all the crossing points except the ones on the far right border # to get the single cells for i, pos in enumerate([pos for pos in range(89) if (pos + 1) % 10 != 0]): # warp the perspective of the cell to match a square. # the target image "transformed" is slightly smaller than "square" to # cut off noise on the borders square = np.float32([[-10, -10], [40, -10], [-10, 40], [40, 40]]) # get the corner points for the cell i quad = np.float32([crossing_points[pos], crossing_points[pos + 1], crossing_points[pos + 10], crossing_points[pos + 11]]) matrix = cv2.getPerspectiveTransform(quad, square) transformed = cv2.warpPerspective(src, matrix, (30, 30)) # # perform the ocr # # for the tesseract api it is neccessary to convert the image to the # old style opencv iplimage ipl = iplimage_from_array(transformed) tesseract.SetCvImage(ipl, api) ocr_text = api.GetUTF8Text() # # Number conversion # try: # try to convert the found text to an integer numbers.append(int(ocr_text)) except: # skip the frame if ocr returned no number but we found a contour contours, _ = cv2.findContours(image=cv2.bitwise_not(transformed), mode=cv2.RETR_LIST, method=cv2.CHAIN_APPROX_SIMPLE) for cnt in contours: area = cv2.contourArea(cnt) if area > 100: return # if no number or contour has been found the cell must be empty numbers.append(0) # # draw the recognized numbers into the image for x in range(9): for y in range(9): number = numbers[y * 9 + x] if not number == 0: draw_str(src, (75 + x * 50, 75 + y * 50), str(number)) if args.debug: cv2.imshow('src', src) cv2.imshow('Detected', src) # try to solve the sudoku using the Sudoku class try: solved_sudoku = sudoku.Sudoku(numbers) solved_sudoku.solve() # show the solution in console if args.debug: print(solved_sudoku) print() # newline # show solution image. Pass the sudoku source to enable colouring source_sudoku = sudoku.Sudoku(numbers) solution_image = draw_sudoku(solved_sudoku, source_sudoku) cv2.imshow('solution', solution_image) except: # no solutions found pass
def time_solver(sudoku_string): t = timeit.default_timer() s = sudoku.Sudoku(sudoku_string) s.solve() return timeit.default_timer() - t
def f2(): s = sudoku.Sudoku() for i in range(9): s[i] = i + 1 return sudoku.solve_sat(s)
import sudoku as sdk # Example program # This example program solve the same sudoku with the simplest solver # This solver works on simple logic, so it cannot solve all sodokus, # but it is simple and quick. filename = '../sudokus/1' maximum_iterations = 20 debug_level = 3 # This decides how much information to print out sudoku = sdk.Sudoku() sudoku.Load(filename) print(' GIVENS') print(sudoku) solver = sdk.SinglesSolver(sudoku, maximum_iterations, debug_level) solver.Execute()
result = self.rec_backtracking_search({}, csp) return result if __name__ == '__main__': ''' Some board test cases, each string is a flat enumeration of all the board positions where . indicates an unfilled location Impossible: 123456789.........123456789123456789123456789123456789123456789123456789123456789 Easy ..3.2.6..9..3.5..1..18.64....81.29..7.......8..67.82....26.95..8..2.3..9..5.1.3.. Easy ...7.46.3..38...51.1.9.327..34...76....6.8....62...98..473.6.1.68...13..3.12.5... Difficult ..5...1.3....2.........176.7.49....1...8.4...3....7..8.3.5....2....9....4.6...9.. ''' board = sudoku.Sudoku( '12.456789.........12.45678912.45678912.45678912.45678912.45678912.45678912.456789' ) #Accessing the board as a csp, i.e. display the variable and domains #See the extra document for exapmles of how to use the CSP class # Display this nonsensical board board.display(board) #Show the "flat" variables print(board.variables) #show the domeians (curr_domains beocmes populated by infer_assignment()) print(board.curr_domains) '''You'll need to manipulate the CSP domains and variables, so here are some exampels''' # this is a list of (variable, domain value) pairs that you can use to keep track
def __events(self): for event in pg.event.get(): if event.type == pg.QUIT: self.__quit() if event.type == pg.KEYDOWN: if event.key == pg.K_ESCAPE: self.__quit() # the size of the sudoku puzzle we will be solving sudoku_size = 9 # get the genetic algorithm settings settings = GA.get_ga_settings(sudoku_size) # construct a new sudoku puzzle and randomize it board = sudoku.Sudoku(sudoku_size) board.randomize() # construct the sudoku visualization vis = SudokuVis(board, settings) # keep some stats about our population's evolution so we can plot them max_pop_fitness = [] min_pop_fitness = [] avg_pop_fitness = [] # define an initial population to pass into the GA population = [] for i in range(settings.population_size): population.append([ random.choice(settings.individual_values)
def f1(): s = sudoku.Sudoku() return sudoku.solve(s)