Пример #1
0
 def check_solver(self):
     # easy Sudokus (no backtracking required). From New York Times, 31 May 2020 - 2 June 2020
     puzzles = [
         '280070309600104007745080006064830100102009800000201930006050701508090020070402050',
         '910780200027001894684000300000846001740059080009000050106093008000500706002070130'
     ]
     solutions = [
         '281576349693124587745983216964835172132749865857261934426358791518697423379412658',
         '913784265527361894684925317235846971741259683869137452176493528398512746452678139'
     ]
     for puzzle, solution in zip(puzzles, solutions):
         puzzle, solution = list(map(parse, [puzzle, solution]))
         my_solution, done, _ = solveSudoku(puzzle, verbose=False)
         self.assertTrue(done)
         self.assertTrue(grid_equal(solution, my_solution))
     # medium to hard Sudoku (some backtracking). From New York Times, 31 May 2020 - 2 June 2020
     puzzles = [
         '100020400035040900704000001800000000091032080000100097070900600000000000000450000',
         '000832067000600200800700010010020000509004700000008000007000940000005000402000500',
         '000010030009005008804006025000000600008004000120087000300900200065008000900000000'
     ]
     solutions = [
         '189327465235641978764895321827569143491732586653184297372918654546273819918456732',
         '195832467743651298826749315318927654569314782274568139657283941931475826482196573',
         '752819436639245718814736925473592681598164372126387549387951264265478193941623857'
     ]
     for puzzle, solution in zip(puzzles, solutions):
         puzzle, solution = list(map(parse, [puzzle, solution]))
         my_solution, done, _ = solveSudoku(puzzle, verbose=False)
         self.assertTrue(done)
         self.assertTrue(grid_equal(solution, my_solution))
Пример #2
0
 def solve_X_sudoku(self):
     puzzles = [
         ('060050200000000060532008000000049103000100050000000007005010008004000006000006500',
          '968751234741392865532468719257649183493187652186235497675914328814523976329876541'
          ),
         ('030040200520006700000000000080020170000070000050000003400000032000600000000080691',
          '638547219521936748749218365984325176362179584157864923496751832813692457275483691'
          )
     ]
     for puzzle, solution in puzzles:
         puzzle, solution = str2grid(puzzle), str2grid(solution)
         solution_set, done, info = solveSudoku(puzzle,
                                                verbose=False,
                                                all_solutions=False,
                                                is_X_Sudoku=True)
         self.assertTrue(done)
         solver_sol = str2grid(solution_set[0])
         self.assertTrue(grid_equal(solution, solver_sol))
Пример #3
0
 def candidates_test(self):
     grid = [[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, 7, 9]]
     candidates = [[
         set(),
         set(), {1, 2, 4}, {2, 6},
         set(), {8, 2, 4, 6}, {8, 1, 4, 9}, {1, 2, 4, 9}, {8, 2, 4}
     ],
                   [
                       set(), {2, 4, 7}, {2, 4, 7},
                       set(),
                       set(),
                       set(), {8, 3, 4, 7}, {2, 3, 4}, {8, 2, 4, 7}
                   ],
                   [{1, 2},
                    set(),
                    set(), {2, 3}, {3, 4}, {2, 4}, {1, 3, 4, 5, 7},
                    set(), {2, 4, 7}],
                   [
                       set(), {1, 2, 5}, {1, 2, 5, 9}, {9, 5, 7},
                       set(), {1, 4, 7}, {9, 4, 5, 7}, {9, 2, 4, 5},
                       set()
                   ],
                   [
                       set(), {2, 5}, {9, 2, 5, 6},
                       set(), {5},
                       set(), {9, 5, 7}, {9, 2, 5},
                       set()
                   ],
                   [
                       set(), {1, 5}, {1, 3, 5, 9}, {9, 5},
                       set(), {1, 4}, {8, 9, 4, 5}, {9, 4, 5},
                       set()
                   ],
                   [{1, 3, 9},
                    set(), {1, 3, 4, 5, 7, 9}, {3, 5, 7}, {3, 5}, {7},
                    set(),
                    set(), {4}],
                   [{2, 3}, {8, 2, 7}, {2, 3, 7},
                    set(),
                    set(),
                    set(), {3, 6}, {3},
                    set()],
                   [{1, 2, 3}, {1, 2, 4, 5}, {1, 2, 3, 4, 5}, {2, 3, 5, 6},
                    set(), {2, 6}, {1, 3, 4, 6},
                    set(),
                    set()]]
     s = Sudoku(grid)
     self.assertTrue(grid_equal(candidates, s.candidates))
     # test uniques
     inds = [(0, j) for j in range(9)]  # no unique candidates
     #self.assertEqual(s.get_unique(inds), [])
     self.assertEqual(s.get_unique(inds, type=[1]), [])
     inds = [(7, j)
             for j in range(9)]  # uniques: 8 at (7, 1)  and 6 at (7, 6)
     #self.assertEqual(s.get_unique(inds), [([(7, 6)], [6]), ([(7, 1)], [8])] ) #[(6, (7, 6)), (8, (7, 1))])
     self.assertEqual(s.get_unique(inds, type=[1]), [([(7, 6)], [6]),
                                                     ([(7, 1)], [8])])
     inds = s.get_box_inds(5, 6)  # middle right box. unique 8 at (5,6)
     #self.assertEqual(s.get_unique(inds), [([(5, 6)], [8])])
     self.assertEqual(s.get_unique(inds, type=[1]), [([(5, 6)], [8])])
     # test erase function
     s.place_and_erase(0, 2, 1, constraint_prop=False)
     self.assertEqual(s.candidates[0], [
         set(),
         set(),
         set(), {2, 6},
         set(), {8, 2, 4, 6}, {8, 4, 9}, {2, 4, 9}, {8, 2, 4}
     ])
     col = [s.candidates[i][2] for i in range(9)]
     self.assertEqual(col, [
         set(), {2, 4, 7},
         set(), {2, 5, 9}, {2, 5, 6, 9}, {3, 5, 9}, {3, 4, 5, 7, 9},
         {2, 3, 7}, {2, 3, 4, 5}
     ])
Пример #4
0
 def check_solved_puzzles(self):
     # these puzzles were sovled with the solver. This is to check solutions still hold.
     puzzles = [
         # from https://dev.to/aspittel/how-i-finally-wrote-a-sudoku-solver-177g
         (
             # very easy puzzle
             '530070000600195000098000060800060003400803001700020006060000280000419005000080079',
             '534678912672195348198342567859761423426853791713924856961537284287419635345286179'
         ),
         # https://www.nytimes.com/puzzles/sudoku/
         ('106000050070030004090005200002060007000108000047020000000000803003200006000000002',
          '186742359275839164394615278812564937639178425547923681721456893953281746468397512'
          ),
         # Arto Inkala Puzzles from  https://norvig.com/sudoku.html
         (
             # not that hard actually
             '85...24..72......9..4.........1.7..23.5...9...4...........8..7..17..........36.4.',
             '859612437723854169164379528986147352375268914241593786432981675617425893598736241'
         ),
         (
             # have to make at least 3 guesses
             '..53.....8......2..7..1.5..4....53...1..7...6..32...8..6.5....9..4....3......97..',
             '145327698839654127672918543496185372218473956753296481367542819984761235521839764'
         ),
         (
             # have to make at least 3 guesses
             '800000000003600000070090200050007000000045700000100030001000068008500010090000400',
             '812753649943682175675491283154237896369845721287169534521974368438526917796318452'
         ),
         # 17 clue puzzle from https://theconversation.com/good-at-sudoku-heres-some-youll-never-complete-5234
         (
             #  1 unique solution. Very fun to do
             '000700000100000000000430200000000006000509000000000418000081000002000050040000300',
             '264715839137892645598436271423178596816549723759623418375281964982364157641957382'
         ),
         # 17 clue puzzle from  https://cracking-the-cryptic.web.app/sudoku/PMhgbbQRRb
         ('029000400000500100040000000000042000600000070500000000700300005010090000000000060',
          '329816457867534192145279638931742586684153279572968314796321845418695723253487961'
          ),
         # https://www.sudokuwiki.org/Weekly_Sudoku.asp
         (  # May 24 2020 Extreme -> requires multiple diabolical+extreme strategies
             '003100720700000500050240030000720000006000800000014000060095080005000009049002600',
             '693158724724963518851247936538726491416539872972814365267495183385671249149382657'
         ),
         (
             #403 'unsolvable' - no known logical solution
             '100200000065074800070006900004000000050008704000030000000000600080000057006007089',
             '138259476965374821472186935824761593653928714791435268517893642389642157246517389'
         ),
         (
             #404 'unsolvable' - no known logical solution
             '400009200000010080005400006004200001050030060700005300500007600090060000002800007',
             '468579213279613485135428796384296571951734862726185349513947628897362154642851937'
         ),
         (
             # June 7 2020 Extreme
             '080001206000020000020305040060010900002050400008000010030704050000030000406100080',
             '785941236143628795629375841564213978912857463378469512231784659897536124456192387'
         )
     ]
     for puzzle, solution in puzzles:
         puzzle, solution = str2grid(puzzle), str2grid(solution)
         solution_set, done, _ = solveSudoku(puzzle,
                                             verbose=False,
                                             all_solutions=False)
         self.assertTrue(done)
         solver_sol = str2grid(solution_set[0])
         self.assertTrue(grid_equal(solution, solver_sol))
Пример #5
0
 def candidates_advanced(self):
     grid = [[0, 8, 0, 0, 0, 1, 2, 0, 6], [0, 0, 0, 0, 2, 0, 0, 0, 0],
             [0, 2, 0, 3, 0, 5, 0, 4, 0], [0, 6, 0, 0, 1, 0, 9, 0, 0],
             [0, 0, 2, 0, 5, 0, 4, 0, 0], [0, 0, 8, 0, 0, 0, 0, 1, 0],
             [0, 3, 0, 7, 0, 4, 0, 5, 0], [0, 0, 0, 0, 3, 0, 0, 0, 0],
             [4, 0, 6, 1, 0, 0, 0, 8,
              0]]  # June 7 Extreme 'https://www.sudokuwiki.org
     s = Sudoku(grid)
     candidates = [[{9, 3, 5, 7},
                    set(), {3, 4, 5, 7, 9}, {9, 4}, {9, 4, 7},
                    set(),
                    set(), {9, 3, 7},
                    set()],
                   [{1, 3, 5, 6, 7, 9}, {1, 4, 5, 7, 9}, {1, 3, 4, 5, 7, 9},
                    {8, 9, 4, 6},
                    set(), {8, 9, 6, 7}, {1, 3, 5, 7, 8}, {9, 3, 7},
                    {1, 3, 5, 7, 8, 9}],
                   [{1, 9, 6, 7},
                    set(), {1, 9, 7},
                    set(), {8, 9, 6, 7},
                    set(), {8, 1, 7},
                    set(), {8, 1, 9, 7}],
                   [{3, 5, 7},
                    set(), {3, 4, 5, 7}, {8, 2, 4},
                    set(), {8, 2, 3, 7},
                    set(), {2, 3, 7}, {2, 3, 5, 7, 8}],
                   [{1, 3, 9, 7}, {1, 9, 7},
                    set(), {8, 9, 6},
                    set(), {3, 6, 7, 8, 9},
                    set(), {3, 6, 7}, {8, 3, 7}],
                   [{9, 3, 5, 7}, {9, 4, 5, 7},
                    set(), {9, 2, 4, 6}, {9, 4, 6, 7}, {2, 3, 6, 7, 9},
                    {3, 5, 6, 7},
                    set(), {2, 3, 5, 7}],
                   [{8, 1, 2, 9},
                    set(), {1, 9},
                    set(), {8, 9, 6},
                    set(), {1, 6},
                    set(), {1, 2, 9}],
                   [{1, 2, 5, 7, 8, 9}, {1, 5, 9, 7}, {1, 5, 9, 7},
                    {2, 5, 6, 8, 9},
                    set(), {8, 9, 2, 6}, {1, 6, 7}, {9, 2, 6, 7},
                    {1, 2, 4, 7, 9}],
                   [
                       set(), {9, 5, 7},
                       set(),
                       set(), {9}, {9, 2}, {3, 7},
                       set(), {9, 2, 3, 7}
                   ]]
     self.assertTrue(grid_equal(candidates, s.candidates))
     inds = [(i, 0) for i in range(9)]
     #self.assertEqual(s.get_pairs(inds), [([(6, 0), (7, 0)], (2, 8))])
     uniques = s.get_unique(inds, type=[2])[0]
     uniques[0].sort()
     self.assertEqual(uniques, ([(6, 0), (7, 0)], (2, 8)))
     grid = [[0, 0, 0, 0, 0, 1, 0, 3, 0], [2, 3, 1, 0, 9, 0, 0, 0, 0],
             [0, 6, 5, 0, 0, 3, 1, 0, 0], [6, 7, 8, 9, 2, 4, 3, 0, 0],
             [1, 0, 3, 0, 5, 0, 0, 0, 6], [0, 0, 0, 1, 3, 6, 7, 0, 0],
             [0, 0, 9, 3, 6, 0, 5, 7, 0], [0, 0, 6, 0, 1, 9, 8, 4, 3],
             [3, 0, 0, 0, 0, 0, 0, 0,
              0]]  # https://www.sudokuwiki.org/Hidden_Candidates#HP
     s = Sudoku(grid)
     inds = [(0, j) for j in range(9)]
     uniques = s.get_unique(inds, type=[3])[0]
     uniques[0].sort()
     self.assertEqual(uniques, ([(0, 3), (0, 6), (0, 8)], (2, 5, 6)))
     s.candidates[0][8] = {2, 5}
     inds = [(i, 8) for i in range(9)]
     uniques = s.get_unique(inds, type=[3])[0]
     uniques[0].sort()
     self.assertEqual(uniques, ([(1, 8), (2, 8), (5, 8)], (4, 8, 7)))