Beispiel #1
0
def test_unique_rectangle_block_apart():
    sudoku = make_sudoku_with_marks(
        [
            [9, 0, 1, 0, 3, 0, 5, 0, 0],
            [0, 0, 7, 8, 1, 9, 0, 0, 0],
            [0, 2, 0, 4, 5, 6, 1, 9, 7],
            [1, 0, 2, 9, 0, 0, 6, 0, 5],
            [0, 0, 0, 6, 7, 1, 0, 2, 4],
            [6, 0, 0, 3, 2, 5, 8, 0, 0],
            [0, 1, 5, 0, 9, 0, 4, 6, 3],
            [0, 0, 6, 5, 0, 0, 0, 0, 0],
            [0, 0, 0, 1, 6, 3, 0, 5, 0],
        ],
        box_size=BoxSize(3, 3),
    )

    unique_rectangle = techniques.UniqueRectangle(sudoku).first()
    assert unique_rectangle.combination.cells == [
        Cell(position=Position(0, 3, 1), candidates={2, 7}),
        Cell(position=Position(0, 5, 1), candidates={2, 7}),
        Cell(position=Position(6, 3, 7), candidates={2, 7}),
        Cell(position=Position(6, 5, 7), candidates={2, 7, 8}),
    ]

    assert unique_rectangle.changes == [
        Cell(position=Position(6, 5, 7), candidates={8})
    ]
Beispiel #2
0
def test_locked_candidate_in_a_row():
    sudoku = make_sudoku_with_marks(
        [
            [9, 0, 0, 5, 3, 1, 2, 8, 0],
            [0, 2, 5, 7, 0, 4, 9, 3, 0],
            [0, 3, 0, 0, 0, 2, 0, 4, 0],
            [4, 8, 1, 2, 5, 7, 6, 9, 3],
            [3, 5, 9, 0, 0, 8, 0, 0, 2],
            [7, 6, 2, 3, 1, 9, 8, 5, 4],
            [0, 1, 0, 0, 0, 0, 0, 6, 8],
            [6, 0, 8, 1, 0, 5, 3, 0, 0],
            [0, 0, 3, 8, 7, 6, 0, 0, 0],
        ],
        box_size=BoxSize(3, 3),
    )

    locked_candidate = techniques.LockedCandidate(sudoku).first()

    assert locked_candidate.combination.cells == [
        Cell(position=Position(6, 3, 7), candidates={4, 9}),
        Cell(position=Position(6, 4, 7), candidates={2, 4, 9}),
    ]
    assert locked_candidate.combination.values == [9]

    assert locked_candidate.changes == [
        Cell(position=Position(7, 4, 7), candidates={2, 4})
    ]
Beispiel #3
0
def test_naked_triplet():
    sudoku = make_sudoku_with_marks(
        [
            [9, 2, 6, 7, 3, 5, 4, 0, 0],
            [0, 0, 0, 6, 4, 9, 7, 2, 5],
            [7, 4, 5, 8, 2, 1, 9, 3, 6],
            [0, 1, 0, 0, 0, 8, 6, 4, 0],
            [5, 0, 4, 0, 0, 0, 8, 0, 0],
            [8, 6, 9, 1, 7, 4, 3, 5, 2],
            [0, 0, 0, 0, 8, 0, 0, 0, 0],
            [0, 0, 0, 9, 1, 0, 0, 6, 0],
            [0, 0, 0, 4, 0, 3, 1, 0, 0],
        ],
        box_size=BoxSize(3, 3),
    )

    naked_triplet = techniques.NakedTriplet(sudoku).first()

    assert naked_triplet.combination.cells == [
        Cell(position=Position(6, 7, 8), candidates={7, 9}),
        Cell(position=Position(8, 7, 8), candidates={7, 8, 9}),
        Cell(position=Position(8, 8, 8), candidates={7, 8, 9}),
    ]
    assert naked_triplet.combination.values == [7, 8, 9]

    by_position = operator.attrgetter("position")
    assert sorted(naked_triplet.changes, key=by_position) == [
        Cell(position=Position(6, 8, 8), candidates={3, 4}),
        Cell(position=Position(7, 8, 8), candidates={3, 4}),
    ]
Beispiel #4
0
def test_unique_rectangle_not_found():
    sudoku = make_sudoku_with_marks(
        [
            [9, 2, 6, 7, 3, 5, 4, 0, 0],
            [0, 0, 0, 6, 4, 9, 7, 2, 5],
            [7, 4, 5, 8, 2, 1, 9, 3, 6],
            [0, 1, 0, 0, 0, 8, 6, 4, 0],
            [5, 0, 4, 0, 0, 0, 8, 0, 0],
            [8, 6, 9, 1, 7, 4, 3, 5, 2],
            [0, 0, 0, 0, 8, 0, 0, 0, 0],
            [0, 0, 0, 9, 1, 0, 0, 6, 0],
            [0, 0, 0, 4, 0, 3, 1, 0, 0],
        ],
        box_size=BoxSize(3, 3),
    )

    sudoku.update([
        Cell(position=Position(6, 0, 6), candidates={1, 6}),
        Cell(position=Position(6, 8, 8), candidates={3, 4}),
        Cell(position=Position(7, 0, 6), candidates={3, 4}),
        Cell(position=Position(7, 8, 8), candidates={3, 4}),
    ])

    with pytest.raises(techniques.NotFound):
        techniques.UniqueRectangle(sudoku).first()
Beispiel #5
0
def _random_initial_cells(box_size: BoxSize) -> List[Cell]:
    size = box_size.width * box_size.length
    all_values = set(range(1, size + 1))

    values = random.sample(all_values, k=size)
    box_values = [
        values[i * box_size.length:i * box_size.length + box_size.length]
        for i in range(box_size.width)
    ]

    while True:  # pragma: no branch
        row_values = random.sample(all_values - set(box_values[0]),
                                   k=box_size.length)
        used_values = [sorted(box_values[i]) for i in range(1, box_size.width)]
        if sorted(row_values) not in used_values:
            break

    row_values += random.sample(all_values.difference(box_values[0],
                                                      row_values),
                                k=box_size.length)

    return [
        Cell(
            position=Position(row=i, column=j, box=box_size.sequential(i, j)),
            value=box_values[i][j],
        ) for i in range(box_size.width) for j in range(box_size.length)
    ] + [
        Cell(
            position=Position(row=0, column=i, box=box_size.sequential(0, i)),
            value=value,
        ) for i, value in enumerate(row_values, start=box_size.length)
    ]
Beispiel #6
0
def test_hidden_single():
    sudoku = make_sudoku_with_marks(
        [
            [9, 0, 6, 7, 0, 5, 0, 0, 0],
            [0, 0, 0, 0, 0, 9, 0, 2, 5],
            [7, 4, 0, 0, 0, 1, 0, 0, 0],
            [0, 1, 0, 0, 0, 0, 6, 4, 0],
            [5, 0, 0, 0, 0, 0, 0, 0, 0],
            [8, 6, 9, 1, 0, 0, 3, 0, 0],
            [0, 0, 0, 0, 8, 0, 0, 0, 0],
            [0, 0, 0, 9, 0, 0, 0, 6, 0],
            [0, 0, 0, 4, 0, 3, 1, 0, 0],
        ],
        box_size=BoxSize(3, 3),
    )

    hidden_single = techniques.HiddenSingle(sudoku).first()

    assert hidden_single.combination.cells == [
        Cell(position=Position(1, 6, 2), candidates={4, 7, 8})
    ]
    assert hidden_single.combination.values == [7]

    by_position = operator.attrgetter("position")
    assert sorted(hidden_single.changes, key=by_position) == [
        Cell(position=Position(1, 6, 2), value=7),
        Cell(position=Position(4, 6, 5), candidates={2, 8, 9}),
        Cell(position=Position(6, 6, 8), candidates={2, 4, 5, 9}),
        Cell(position=Position(7, 6, 8), candidates={2, 4, 5, 8}),
    ]
Beispiel #7
0
def test_unique_rectangle():
    sudoku = make_sudoku_with_marks(
        [
            [0, 6, 0, 8, 0, 2, 3, 7, 1],
            [3, 0, 7, 1, 6, 5, 8, 0, 4],
            [0, 8, 1, 3, 7, 0, 5, 6, 0],
            [8, 7, 4, 9, 2, 3, 1, 5, 6],
            [9, 1, 3, 6, 5, 8, 2, 4, 7],
            [6, 0, 0, 4, 1, 7, 9, 3, 8],
            [0, 3, 8, 0, 0, 0, 6, 1, 5],
            [0, 0, 6, 0, 8, 1, 4, 0, 3],
            [1, 4, 0, 5, 3, 6, 7, 8, 0],
        ],
        box_size=BoxSize(3, 3),
    )

    assert len(list(techniques.UniqueRectangle(sudoku))) == 1

    unique_rectangle = techniques.UniqueRectangle(sudoku).first()
    assert unique_rectangle.combination.cells == [
        Cell(position=Position(6, 0, 6), candidates={2, 7}),
        Cell(position=Position(6, 3, 7), candidates={2, 7}),
        Cell(position=Position(7, 0, 6), candidates={2, 5, 7}),
        Cell(position=Position(7, 3, 7), candidates={2, 7}),
    ]
    assert unique_rectangle.combination.values == [2, 7]
    assert unique_rectangle.changes == [
        Cell(position=Position(7, 0, 6), candidates={5}),
    ]
Beispiel #8
0
def test_lone_single():
    sudoku = make_sudoku_with_marks(
        [
            [0, 0, 0, 0, 9, 0, 1, 0, 0],
            [0, 0, 0, 0, 0, 2, 3, 0, 0],
            [0, 0, 7, 0, 0, 1, 8, 2, 5],
            [6, 0, 4, 0, 3, 8, 9, 0, 0],
            [8, 1, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 9, 0, 0, 0, 0, 0, 8],
            [1, 7, 0, 0, 0, 0, 6, 0, 0],
            [9, 0, 0, 0, 1, 0, 7, 4, 3],
            [4, 0, 3, 0, 6, 0, 0, 0, 1],
        ],
        box_size=BoxSize(3, 3),
    )
    lone_single = techniques.LoneSingle(sudoku).first()

    assert lone_single.combination.cells == [
        Cell(position=Position(1, 0, 0), candidates={5})
    ]
    assert lone_single.combination.values == [5]

    by_position = operator.attrgetter("position")
    assert sorted(lone_single.changes, key=by_position) == [
        Cell(position=Position(0, 0, 0), candidates={2, 3}),
        Cell(position=Position(0, 1, 0), candidates={2, 3, 4, 6, 8}),
        Cell(position=Position(0, 2, 0), candidates={2, 6, 8}),
        Cell(position=Position(1, 0, 0), value=5),
        Cell(position=Position(1, 1, 0), candidates={4, 6, 8, 9}),
        Cell(position=Position(1, 2, 0), candidates={1, 6, 8}),
        Cell(position=Position(1, 3, 1), candidates={4, 6, 7, 8}),
        Cell(position=Position(1, 4, 1), candidates={4, 7, 8}),
        Cell(position=Position(5, 0, 3), candidates={2, 3, 7}),
    ]
Beispiel #9
0
def test_sudoku():
    sudoku = Sudoku(
        Cell(position=Position(0, 0, 0), value=2),
        Cell(position=Position(0, 1, 0), candidates=set()),
        box_size=BoxSize(3, 3),
    )
    assert sudoku[0, 0].value == 2
    assert sudoku[0, 1].candidates == set()
    assert sudoku[0, 2].value is None
    assert len(sudoku[0, 2].candidates) == 0
Beispiel #10
0
def test_locked_candidate_not_found():
    sudoku = make_sudoku_with_marks(
        [
            [2, 0, 0, 5, 9, 3, 1, 0, 0],
            [5, 0, 1, 0, 0, 2, 3, 0, 0],
            [3, 9, 7, 6, 4, 1, 8, 2, 5],
            [6, 0, 4, 0, 3, 8, 9, 0, 0],
            [8, 1, 0, 0, 0, 0, 0, 3, 6],
            [7, 3, 9, 0, 0, 6, 0, 0, 8],
            [1, 7, 0, 3, 0, 4, 6, 0, 0],
            [9, 0, 0, 0, 1, 5, 7, 4, 3],
            [4, 0, 3, 0, 6, 0, 0, 0, 1],
        ],
        box_size=BoxSize(3, 3),
    )

    sudoku.update([
        Cell(position=Position(1, 1, 0), candidates={4, 6}),
        Cell(position=Position(1, 7, 2), candidates={6, 9}),
        Cell(position=Position(1, 8, 2), candidates={4, 9}),
        Cell(position=Position(3, 3, 4), candidates={1, 2}),
        Cell(position=Position(8, 1, 6), candidates={2, 5, 8}),
        Cell(position=Position(8, 3, 7), candidates={7, 9}),
        Cell(position=Position(8, 5, 7), candidates={7, 9}),
        Cell(position=Position(8, 6, 8), candidates={2, 5}),
        Cell(position=Position(8, 7, 8), candidates={5, 8}),
    ])

    with pytest.raises(techniques.NotFound):
        techniques.LockedCandidate(sudoku).first()
Beispiel #11
0
def test_combination_as_str():
    combination = techniques.Combination(
        name="Naked Pair",
        cells=[
            Cell(position=Position(6, 3, 7), candidates={2, 5}),
            Cell(position=Position(6, 6, 8), candidates={2, 5}),
        ],
        values=[2, 5],
    )

    assert str(combination) == "Naked Pair: `2, 5` at (6, 3), (6, 6)"
Beispiel #12
0
 def _get_changes(self, combination: Combination) -> List[Cell]:
     eliminated = set(combination.values)
     single = Cell(
         position=combination.cells[0].position,
         value=combination.values[0],
     )
     return [
         Cell(position=cell.position,
              candidates=cell.candidates - eliminated)
         for cell in self.sudoku.intersection(single)
         if cell.candidates and cell.candidates & eliminated
     ] + [single]
Beispiel #13
0
def test_locked_candidate_in_a_box():
    sudoku = make_sudoku_with_marks(
        [
            [2, 0, 0, 5, 9, 3, 1, 0, 0],
            [5, 0, 1, 0, 0, 2, 3, 0, 0],
            [3, 9, 7, 6, 4, 1, 8, 2, 5],
            [6, 0, 4, 0, 3, 8, 9, 0, 0],
            [8, 1, 0, 0, 0, 0, 0, 3, 6],
            [7, 3, 9, 0, 0, 6, 0, 0, 8],
            [1, 7, 0, 3, 0, 4, 6, 0, 0],
            [9, 0, 0, 0, 1, 5, 7, 4, 3],
            [4, 0, 3, 0, 6, 0, 0, 0, 1],
        ],
        box_size=BoxSize(3, 3),
    )

    sudoku.update([
        Cell(position=Position(1, 1, 0), candidates={4, 6}),
        Cell(position=Position(1, 7, 2), candidates={6, 9}),
        Cell(position=Position(1, 8, 2), candidates={4, 9}),
        Cell(position=Position(8, 3, 7), candidates={7, 9}),
        Cell(position=Position(8, 7, 8), candidates={5, 8}),
    ])

    locked_candidate = techniques.LockedCandidate(sudoku).first()

    assert locked_candidate.combination.cells == [
        Cell(position=Position(3, 7, 5), candidates={1, 5, 7}),
        Cell(position=Position(3, 8, 5), candidates={2, 7}),
    ]
    assert locked_candidate.combination.values == [7]

    assert locked_candidate.changes == [
        Cell(position=Position(3, 3, 4), candidates={1, 2})
    ]
Beispiel #14
0
    def count(sudoku: Sudoku) -> None:
        nonlocal total_solutions
        nonlocal total_branch_factor
        _sudoku = solvers.eliminate(sudoku)

        cells = sorted(
            (cell for cell in _sudoku.cells() if not cell.value),
            key=operator.attrgetter("candidates"),
        )

        for cell in cells:
            branch_factor = len(cell.candidates)
            for candidate in cell.candidates:
                _sudoku.update([Cell(position=cell.position, value=candidate)])
                try:
                    count(_sudoku)
                except (exceptions.InvalidSudoku, exceptions.NoCandidates):
                    pass
                else:
                    total_solutions += 1
                    if total_solutions > 1:
                        raise exceptions.MultipleSolutions
                    total_branch_factor += pow(branch_factor - 1, 2)
                _sudoku.update([cell])
            else:
                raise exceptions.NoCandidates
Beispiel #15
0
 def _get_changes(self, combination: Combination) -> List[Cell]:
     eliminated = set(combination.values)
     return [
         Cell(position=cell.position, candidates=diff)
         for cell in combination.cells
         if (diff := cell.candidates - eliminated)
     ]
Beispiel #16
0
 def _get_changes(self, combination: Combination) -> List[Cell]:
     eliminated = set(combination.values)
     return [
         Cell(position=c.position, candidates=c.candidates - eliminated)
         for c in self.sudoku.intersection(
             *[x for x in combination.cells[::2]])
         if c.candidates and c.candidates & eliminated
     ]
Beispiel #17
0
 def _get_changes(self, combination: Combination) -> List[Cell]:
     result = []
     for cell in combination.cells:
         candidates = self._get_candidates(cell)
         if not cell.candidates or cell.candidates - candidates:
             result.append(
                 Cell(position=cell.position, candidates=candidates))
     return result
Beispiel #18
0
def test_hint_for_invalid_sudoku(rf):
    sudoku = generators.random_sudoku(avg_rank=1)
    sudoku.update(techniques.BulkPencilMarking(sudoku).first().changes)
    sudoku.update(
        [
            Cell(position=Position(0, 0, 0), value=1),
            Cell(position=Position(0, 1, 0), value=1),
        ]
    )

    url = reverse("hint")
    serializer = serializers.SudokuSerializer(sudoku)
    request = rf.post(url, data=serializer.data, content_type="application/json")
    response = views.Hints.as_view()(request)

    content = json.loads(response.rendered_content)
    assert content["code"] == "invalid_puzzle"
    assert response.status_code == 400
 def create(self, validated_data):
     return Sudoku(
         *[
             Cell(
                 position=Position(*cell["position"]),
                 value=cell["value"],
                 candidates=set(cell["candidates"]),
             ) for cell in validated_data["cells"]
         ],
         box_size=BoxSize(*validated_data["box_size"]),
     )
Beispiel #20
0
def test_pencil_marking_corrects_invalid_mark():
    sudoku = make_sudoku_with_marks(
        [
            [0, 0, 0, 0, 9, 0, 1, 0, 0],
            [0, 0, 0, 0, 0, 2, 3, 0, 0],
            [0, 0, 7, 0, 0, 1, 8, 2, 5],
            [6, 0, 4, 0, 3, 8, 9, 0, 0],
            [8, 1, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 9, 0, 0, 0, 0, 0, 8],
            [1, 7, 0, 0, 0, 0, 6, 0, 0],
            [9, 0, 0, 0, 1, 0, 7, 4, 3],
            [4, 0, 3, 0, 6, 0, 0, 0, 1],
        ],
        box_size=BoxSize(3, 3),
    )

    sudoku.update([Cell(position=Position(1, 0, 0), candidates={3, 5})])
    pencil_marks = techniques.PencilMarking(sudoku).first()
    assert pencil_marks.changes == [
        Cell(position=Position(1, 0, 0), candidates={5})
    ]
Beispiel #21
0
def test_naked_pair():
    sudoku = make_sudoku_with_marks(
        [
            [9, 2, 6, 7, 3, 5, 4, 0, 0],
            [0, 0, 0, 6, 4, 9, 7, 2, 5],
            [7, 4, 5, 8, 2, 1, 9, 3, 6],
            [0, 1, 0, 0, 0, 8, 6, 4, 0],
            [5, 0, 4, 0, 0, 0, 8, 0, 0],
            [8, 6, 9, 1, 7, 4, 3, 5, 2],
            [0, 0, 0, 0, 8, 0, 0, 0, 0],
            [0, 0, 0, 9, 1, 0, 0, 6, 0],
            [0, 0, 0, 4, 0, 3, 1, 0, 0],
        ],
        box_size=BoxSize(3, 3),
    )
    naked_pair = techniques.NakedPair(sudoku).first()

    assert naked_pair.combination.cells == [
        Cell(position=Position(6, 3, 7), candidates={2, 5}),
        Cell(position=Position(6, 6, 8), candidates={2, 5}),
    ]
    assert naked_pair.combination.values == [2, 5]

    by_position = operator.attrgetter("position")
    assert sorted(naked_pair.changes, key=by_position) == [
        Cell(position=Position(6, 0, 6), candidates={1, 3, 4, 6}),
        Cell(position=Position(6, 1, 6), candidates={3, 7, 9}),
        Cell(position=Position(6, 2, 6), candidates={1, 3, 7}),
        Cell(position=Position(6, 5, 7), candidates={6, 7}),
    ]
Beispiel #22
0
def test_xy_wing():
    sudoku = make_sudoku_with_marks(
        [
            [2, 0, 0, 5, 9, 3, 1, 0, 0],
            [5, 0, 1, 0, 0, 2, 3, 0, 0],
            [3, 9, 7, 6, 4, 1, 8, 2, 5],
            [6, 0, 4, 0, 3, 8, 9, 0, 0],
            [8, 1, 0, 0, 0, 0, 0, 3, 6],
            [7, 3, 9, 0, 0, 6, 0, 0, 8],
            [1, 7, 0, 3, 0, 4, 6, 0, 0],
            [9, 0, 0, 0, 1, 5, 7, 4, 3],
            [4, 0, 3, 0, 6, 0, 0, 0, 1],
        ],
        box_size=BoxSize(3, 3),
    )

    sudoku.update([Cell(position=Position(3, 3, 4), candidates={1, 2})])

    xy_wing = techniques.XYWing(sudoku).first()

    assert xy_wing.combination.cells == [
        Cell(position=Position(3, 3, 4), candidates={1, 2}),
        Cell(position=Position(5, 4, 4), candidates={2, 5}),
        Cell(position=Position(5, 7, 5), candidates={1, 5}),
    ]
    assert xy_wing.combination.values == [1]
    assert xy_wing.changes == [
        Cell(position=Position(3, 7, 5), candidates={5, 7}),
        Cell(position=Position(5, 3, 4), candidates={2, 4}),
    ]
Beispiel #23
0
def test_naked_pair_not_found():
    sudoku = make_sudoku_with_marks(
        [
            [9, 2, 6, 7, 3, 5, 4, 0, 0],
            [0, 0, 0, 6, 4, 9, 7, 2, 5],
            [7, 4, 5, 8, 2, 1, 9, 3, 6],
            [0, 1, 0, 0, 0, 8, 6, 4, 0],
            [5, 0, 4, 0, 0, 0, 8, 0, 0],
            [8, 6, 9, 1, 7, 4, 3, 5, 2],
            [0, 0, 0, 0, 8, 0, 0, 0, 0],
            [0, 0, 0, 9, 1, 0, 0, 6, 0],
            [0, 0, 0, 4, 0, 3, 1, 0, 0],
        ],
        box_size=BoxSize(3, 3),
    )
    sudoku.update([
        Cell(position=Position(6, 0, 6), candidates={1, 3, 4, 6}),
        Cell(position=Position(6, 1, 6), candidates={3, 7, 9}),
        Cell(position=Position(6, 2, 6), candidates={1, 3, 7}),
        Cell(position=Position(6, 5, 7), candidates={6, 7}),
    ])

    with pytest.raises(techniques.NotFound):
        techniques.NakedPair(sudoku).first()
Beispiel #24
0
def random_sudoku(avg_rank: int = 150,
                  box_size: BoxSize = BoxSize(3, 3)) -> Sudoku:
    sudoku = Sudoku(*_random_initial_cells(box_size), box_size=box_size)
    solution = solvers.backtrack(sudoku)

    iterations = min(avg_rank, MAX_ITERATIONS)
    for i in range(iterations):
        size = random.randint(1, 2)
        rows = [random.randint(0, solution.size - 1) for _ in range(size)]
        columns = [random.randint(0, solution.size - 1) for _ in range(size)]
        cells = [solution[row, column] for (row, column) in zip(rows, columns)]
        if all(cell.value for cell in cells):
            solution.update([Cell(position=cell.position) for cell in cells])
            try:
                stats.rank(solution)
            except exceptions.MultipleSolutions:
                solution.update(cells)

    return solution
Beispiel #25
0
def backtrack(sudoku: Sudoku) -> Sudoku:
    _sudoku = eliminate(sudoku)

    cells = sorted(
        (cell for cell in _sudoku.cells() if not cell.value),
        key=operator.attrgetter("candidates"),
    )

    for cell in cells:
        for candidate in cell.candidates:
            _sudoku.update([Cell(position=cell.position, value=candidate)])
            try:
                return backtrack(_sudoku)
            except (exceptions.InvalidSudoku, exceptions.NoCandidates):
                pass
            _sudoku.update([cell])
        else:
            raise exceptions.NoCandidates

    return _sudoku
Beispiel #26
0
def test_pencil_marking():
    sudoku = Sudoku.from_list(
        [
            [0, 0, 0, 0, 9, 0, 1, 0, 0],
            [0, 0, 0, 0, 0, 2, 3, 0, 0],
            [0, 0, 7, 0, 0, 1, 8, 2, 5],
            [6, 0, 4, 0, 3, 8, 9, 0, 0],
            [8, 1, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 9, 0, 0, 0, 0, 0, 8],
            [1, 7, 0, 0, 0, 0, 6, 0, 0],
            [9, 0, 0, 0, 1, 0, 7, 4, 3],
            [4, 0, 3, 0, 6, 0, 0, 0, 1],
        ],
        box_size=BoxSize(3, 3),
    )

    pencil_marks = techniques.PencilMarking(sudoku).first()
    assert pencil_marks.changes == [
        Cell(position=Position(0, 0, 0), candidates={2, 3, 5})
    ]
Beispiel #27
0
def test_getitem(sudoku):
    assert sudoku[0, 0] == Cell(position=Position(0, 0, 0), candidates=set())
    assert sudoku[2, 3] == Cell(position=Position(2, 3, 1), value=9)
Beispiel #28
0
def test_cell():
    with pytest.raises(ValueError):
        Cell(position=Position(0, 0, 0), value=2, candidates={2, 6, 9})
Beispiel #29
0
def test_update(sudoku):
    cell_a = Cell(position=Position(0, 0, 0), value=2)
    cell_b = Cell(position=Position(0, 1, 0), candidates=set())
    sudoku.update([cell_a, cell_b])
    assert sudoku[0, 0] is cell_a
    assert sudoku[0, 1] is cell_b