def assert_expected_solver_output(self, puzzle, expected_done, solution_count, solution=None, constraints=None):
     puzzle_grid = SudokuGrid(puzzle)
     my_solution, done, info = SudokuSolver().solveSudoku(puzzle_grid, verbose=False, constraints=constraints)
     #self.assertEqual(info,"")
     self.assertEqual(done, expected_done)
     self.assertEqual(info['solutions'], solution_count)
     if solution:
         self.assertTrue(SudokuGrid(solution) == my_solution, msg=f'solution does not match. Actual: {my_solution}')
Exemple #2
0
 def test_get_indices_for_6x6_regions(self):
     grid = SudokuGrid(size=6)
     regions = grid.get_indices_for_regions()
     self.assertEqual(len(regions), 6)
     self.assertEqual(regions[0], [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1),
                                   (1, 2)])
     self.assertEqual(regions[5], [(4, 3), (4, 4), (4, 5), (5, 3), (5, 4),
                                   (5, 5)])
 def test_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(SudokuGrid().with_matrix(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(self.candidates_equal(s.grid.candidates, 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(SudokuGrid().with_matrix(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.grid.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)) )    
class SudokuSolver:
    grid: SudokuGrid = SudokuGrid()

    def load_grid(self, sudoku_grid):
        self.grid.load(sudoku_grid)

    def print_grid(self):
        self.grid.print()

    def main(self):
        grid = [
            [4, 0, 0, 0, 0, 5, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 1, 9, 8],
            [3, 0, 0, 0, 8, 2, 4, 0, 0],
            [0, 0, 0, 1, 0, 0, 0, 8, 0],
            [9, 0, 3, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 3, 0, 6, 7, 0],
            [0, 5, 0, 0, 0, 9, 0, 0, 0],
            [0, 0, 0, 2, 0, 0, 9, 0, 7],
            [6, 4, 0, 3, 0, 0, 0, 0, 0],
        ]

        self.load_grid(grid)
        # self.solve()
        self.print_grid()
Exemple #5
0
 def test_valid_9x9_grid_with_zeros(self):
     grid = SudokuGrid(
         '100020400035040900704000001800000000091032080000100097070900600000000000000450000'
     )
     self.assertEqual(grid.size, 9)
     self.assertEqual(
         str(grid),
         '100020400035040900704000001800000000091032080000100097070900600000000000000450000'
     )
Exemple #6
0
 def test_valid_9x9_grid_with_dots(self):
     grid = SudokuGrid(
         '1...2.4...35.4.9..7.4.....18.........91.32.8....1...97.7.9..6..............45....'
     )
     self.assertEqual(grid.size, 9)
     self.assertEqual(
         str(grid),
         '100020400035040900704000001800000000091032080000100097070900600000000000000450000'
     )
 def test_impossible(self):
     # impossible
     puzzles = [
         '.....5.8....6.1.43..........1.5........1.6...3.......553.....61........4.........',  
         '12.......34...............5...........5..........................................',  
         '11.......34...............5...........5..........................................',
     ]
     for puzzle in puzzles:
         puzzle = SudokuGrid(puzzle)
         s = Sudoku(puzzle)
         s.flush_candidates()
         self.assertFalse(s.check_possible()[0])
     # possible
     puzzles = [
         '280070309600104007745080006064830100102009800000201930006050701508090020070402050',  
         '000010030009005008804006025000000600008004000120087000300900200065008000900000000',  
         '1.....................................5..........................................',
     ]
     for puzzle in [puzzles[1]]:
         puzzle = SudokuGrid(puzzle)
         s = Sudoku(puzzle)
         s.flush_candidates()
         self.assertTrue(s.check_possible()[0])
Exemple #8
0
 def test_get_region_inds_with_6x6(self):
     grid = SudokuGrid(size=6)
     self.assertEqual(grid.get_region_inds(0, 0), [(0, 0), (0, 1), (0, 2),
                                                   (1, 0), (1, 1), (1, 2)])
     self.assertEqual(grid.get_region_inds(1, 2), [(0, 0), (0, 1), (0, 2),
                                                   (1, 0), (1, 1), (1, 2)])
     self.assertEqual(grid.get_region_inds(4, 3), [(4, 3), (4, 4), (4, 5),
                                                   (5, 3), (5, 4), (5, 5)])
     self.assertEqual(grid.get_region_inds(5, 5), [(4, 3), (4, 4), (4, 5),
                                                   (5, 3), (5, 4), (5, 5)])
class SudokuGridTest(unittest.TestCase):
    g = SudokuGrid()

    def setUp(self):
        grid = [
            [4, 0, 0, 0, 0, 5, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 1, 9, 8],
            [3, 0, 0, 0, 8, 2, 4, 0, 0],
            [0, 0, 0, 1, 0, 0, 0, 8, 0],
            [9, 0, 3, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 3, 0, 6, 7, 0],
            [0, 5, 0, 0, 0, 9, 0, 0, 0],
            [0, 0, 0, 2, 0, 0, 9, 0, 7],
            [6, 4, 0, 3, 0, 0, 0, 0, 0],
        ]
        self.g.load(grid)

    def test_value_is_already_present(self):
        self.assertFalse(self.g.is_possible(0, 0, 4))

    def test_in_line_is_true(self):
        self.assertTrue(self.g.is_possible(1, 0, 9))

    def test_in_line_is_false(self):
        self.assertFalse(self.g.is_possible(1, 0, 5))

    def test_in_column_is_true(self):
        self.assertTrue(self.g.is_possible(0, 1, 5))

    def test_in_column_is_false(self):
        self.assertFalse(self.g.is_possible(0, 1, 6))

    def test_in_square_is_true(self):
        self.assertTrue(self.g.is_possible(1, 1, 2))

    def test_in_square_is_false(self):
        self.assertFalse(self.g.is_possible(1, 1, 3))

    def test_base_printing(self):
        raised = False
        try:
            self.g.print()
        except:
            raised = True

        self.assertFalse(raised, "Printing should not raise an exception")
 def test_find_options(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]
     ]
     s = Sudoku(SudokuGrid().with_matrix(grid))
     self.assertEqual(s.find_options(0, 2), {1, 2, 4})
     self.assertEqual(s.find_options(4, 4), {5})
     self.assertEqual(s.find_options(5, 1), {1, 5})
     self.assertEqual(s.find_options(8, 6), {1, 3, 4, 6})
class SudokuGridTestFirstIssue(unittest.TestCase):
    g = SudokuGrid()

    def setUp(self):
        grid = [
            [4, 2, 1, 0, 0, 5, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 1, 9, 8],
            [3, 0, 0, 0, 8, 2, 4, 0, 0],
            [0, 0, 0, 1, 0, 0, 0, 8, 0],
            [9, 0, 3, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 3, 0, 6, 7, 0],
            [0, 5, 0, 0, 0, 9, 0, 0, 0],
            [0, 0, 0, 2, 0, 0, 9, 0, 7],
            [6, 4, 0, 3, 0, 0, 0, 0, 0],
        ]
        self.g.load(grid)

    def test_is_false(self):
        self.assertFalse(self.g.is_possible(4, 0, 2))
Exemple #12
0
 def test_get_region_inds_with_9x9(self):
     grid = SudokuGrid(size=9)
     self.assertEqual(grid.get_region_inds(0, 0), [(0, 0), (0, 1), (0, 2),
                                                   (1, 0), (1, 1), (1, 2),
                                                   (2, 0), (2, 1), (2, 2)])
     self.assertEqual(grid.get_region_inds(2, 2), [(0, 0), (0, 1), (0, 2),
                                                   (1, 0), (1, 1), (1, 2),
                                                   (2, 0), (2, 1), (2, 2)])
     self.assertEqual(grid.get_region_inds(6, 6), [(6, 6), (6, 7), (6, 8),
                                                   (7, 6), (7, 7), (7, 8),
                                                   (8, 6), (8, 7), (8, 8)])
     self.assertEqual(grid.get_region_inds(8, 8), [(6, 6), (6, 7), (6, 8),
                                                   (7, 6), (7, 7), (7, 8),
                                                   (8, 6), (8, 7), (8, 8)])
 def test_candidates(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(SudokuGrid().with_matrix(grid))
     self.assertTrue(self.candidates_equal(s.grid.candidates, 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.grid.get_region_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.grid.candidates[0], [set(), set(), set(), {2, 6}, set(), {8, 2, 4, 6}, {8, 4, 9}, {2, 4, 9}, {8, 2, 4}])
     col = [s.grid.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}])
Exemple #14
0
 def test_get_indices_for_9x9_regions(self):
     grid = SudokuGrid(size=9)
     regions = grid.get_indices_for_regions()
     self.assertEqual(len(regions), 9)
     self.assertEqual(regions[4], [(3, 3), (3, 4), (3, 5), (4, 3), (4, 4),
                                   (4, 5), (5, 3), (5, 4), (5, 5)])
Exemple #15
0
 def test_invalid_length_string(self):
     with self.assertRaises(Exception):
         SudokuGrid('123443213412214300')
Exemple #16
0
 def test_invalid_digits(self):
     with self.assertRaises(Exception):
         SudokuGrid('1234432134122156')
Exemple #17
0
 def test_empty_grid(self):
     grid = SudokuGrid(size=4)
     self.assertEqual(grid.size, 4)
     self.assertEqual(str(grid), '0000000000000000')
Exemple #18
0
 def test_grid_list_for_6x6(self):
     grid = SudokuGrid(size=6)
     self.assertEqual(len(grid.grid_list), 6)
     self.assertEqual(len(grid.grid_list[0]), 6)
Exemple #19
0
 def test_invalid_size(self):
     with self.assertRaises(Exception) as cm:
         SudokuGrid(size=10)
     self.assertEqual(str(cm.exception), 'Size parameter must be 3..9')
Exemple #20
0
 def test_valid_4x4_grid(self):
     grid = SudokuGrid('1234432134122143')
     self.assertEqual(grid.size, 4)
     self.assertEqual(str(grid), '1234432134122143')