Ejemplo n.º 1
0
def test_backtrack():
    given = Sudoku.from_list(
        [
            [0, 0, 0, 8, 0, 1, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 4, 3],
            [5, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 7, 0, 8, 0, 0],
            [0, 0, 0, 0, 0, 0, 1, 0, 0],
            [0, 2, 0, 0, 3, 0, 0, 0, 0],
            [6, 0, 0, 0, 0, 0, 0, 7, 5],
            [0, 0, 3, 4, 0, 0, 0, 0, 0],
            [0, 0, 0, 2, 0, 0, 6, 0, 0],
        ],
        box_size=BoxSize(3, 3),
    )
    solution = solvers.backtrack(given)
    assert solution.is_solved() is True
    assert solution.is_valid() is True
    assert str(solution) == ("237841569"
                             "186795243"
                             "594326718"
                             "315674892"
                             "469582137"
                             "728139456"
                             "642918375"
                             "853467921"
                             "971253684")
Ejemplo n.º 2
0
def test_eliminate():
    given = 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),
    )

    solution = solvers.eliminate(given)
    assert str(solution) == ("200593100"
                             "501002300"
                             "397641825"
                             "604038900"
                             "810000036"
                             "739006008"
                             "170304600"
                             "900015743"
                             "403060001")
Ejemplo n.º 3
0
def test_steps():
    given = 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),
    )

    assert [step.combination.name for step in solvers.steps(given)] == [
        "Bulk Pencil Marking",
        *["Lone Single"] * 8,
        *["Hidden Single"] * 7,
        "Lone Single",
        "Hidden Single",
        *["Naked Pair"] * 3,
        "Locked Candidate",
        "XY Wing",
        *["Hidden Single"] * 2,
        "Unique Rectangle",
        "Hidden Single",
        *["Lone Single"] * 2,
        "Hidden Single",
        *["Lone Single"] * 28,
    ]
Ejemplo n.º 4
0
def test_plain():
    expected = (
        "┌─────────┬─────────┬─────────╥─────────┬─────────┬─────────╥─────────┬─────────┬─────────┐\n"  # noqa: E501
        "│    2  3 │    2  3 │    2    ║       3 │         │       3 ║         │         │         │\n"  # noqa: E501
        "│    5    │ 4  5  6 │    5  6 ║ 4  5  6 │    9    │ 4  5  6 ║    1    │       6 │ 4     6 │\n"  # noqa: E501
        "│         │    8    │    8    ║ 7  8    │         │ 7       ║         │ 7       │ 7       │\n"  # noqa: E501
        "├─────────┼─────────┼─────────╫─────────┼─────────┼─────────╫─────────┼─────────┼─────────┤\n"  # noqa: E501
        "│         │         │ 1       ║         │         │         ║         │         │         │\n"  # noqa: E501
        "│    5    │ 4  5  6 │    5  6 ║ 4  5  6 │ 4  5    │    2    ║    3    │       6 │ 4     6 │\n"  # noqa: E501
        "│         │    8  9 │    8    ║ 7  8    │ 7  8    │         ║         │ 7     9 │ 7     9 │\n"  # noqa: E501
        "├─────────┼─────────┼─────────╫─────────┼─────────┼─────────╫─────────┼─────────┼─────────┤\n"  # noqa: E501
        "│       3 │       3 │         ║       3 │         │         ║         │         │         │\n"  # noqa: E501
        "│         │ 4     6 │    7    ║ 4     6 │ 4       │    1    ║    8    │    2    │    5    │\n"  # noqa: E501
        "│         │       9 │         ║         │         │         ║         │         │         │\n"  # noqa: E501
        "╞═════════╪═════════╪═════════╬═════════╪═════════╪═════════╬═════════╪═════════╪═════════╡\n"  # noqa: E501
        "│         │    2    │         ║ 1  2    │         │         ║         │ 1       │    2    │\n"  # noqa: E501
        "│    6    │    5    │    4    ║    5    │    3    │    8    ║    9    │    5    │         │\n"  # noqa: E501
        "│         │         │         ║ 7       │         │         ║         │ 7       │ 7       │\n"  # noqa: E501
        "├─────────┼─────────┼─────────╫─────────┼─────────┼─────────╫─────────┼─────────┼─────────┤\n"  # noqa: E501
        "│         │         │    2    ║    2    │    2    │         ║    2    │       3 │    2    │\n"  # noqa: E501
        "│    8    │    1    │    5    ║ 4  5  6 │ 4  5    │ 4  5  6 ║ 4  5    │    5  6 │ 4     6 │\n"  # noqa: E501
        "│         │         │         ║ 7     9 │ 7       │ 7     9 ║         │ 7       │ 7       │\n"  # noqa: E501
        "├─────────┼─────────┼─────────╫─────────┼─────────┼─────────╫─────────┼─────────┼─────────┤\n"  # noqa: E501
        "│    2  3 │    2  3 │         ║ 1  2    │    2    │         ║    2    │ 1     3 │         │\n"  # noqa: E501
        "│    5    │    5    │    9    ║ 4  5  6 │ 4  5    │ 4  5  6 ║ 4  5    │    5  6 │    8    │\n"  # noqa: E501
        "│ 7       │         │         ║ 7       │ 7       │ 7       ║         │ 7       │         │\n"  # noqa: E501
        "╞═════════╪═════════╪═════════╬═════════╪═════════╪═════════╬═════════╪═════════╪═════════╡\n"  # noqa: E501
        "│         │         │    2    ║    2  3 │    2    │       3 ║         │         │    2    │\n"  # noqa: E501
        "│    1    │    7    │    5    ║ 4  5    │ 4  5    │ 4  5    ║    6    │    5    │         │\n"  # noqa: E501
        "│         │         │    8    ║    8  9 │    8    │       9 ║         │    8  9 │       9 │\n"  # noqa: E501
        "├─────────┼─────────┼─────────╫─────────┼─────────┼─────────╫─────────┼─────────┼─────────┤\n"  # noqa: E501
        "│         │    2    │    2    ║    2    │         │         ║         │         │         │\n"  # noqa: E501
        "│    9    │    5  6 │    5  6 ║    5    │    1    │    5    ║    7    │    4    │    3    │\n"  # noqa: E501
        "│         │    8    │    8    ║    8    │         │         ║         │         │         │\n"  # noqa: E501
        "├─────────┼─────────┼─────────╫─────────┼─────────┼─────────╫─────────┼─────────┼─────────┤\n"  # noqa: E501
        "│         │    2    │         ║    2    │         │         ║    2    │         │         │\n"  # noqa: E501
        "│    4    │    5    │    3    ║    5    │    6    │    5    ║    5    │    5    │    1    │\n"  # noqa: E501
        "│         │    8    │         ║ 7  8  9 │         │ 7     9 ║         │    8  9 │         │\n"  # noqa: E501
        "└─────────┴─────────┴─────────╨─────────┴─────────┴─────────╨─────────┴─────────┴─────────┘"  # noqa: E501
    )

    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),
    )
    sudoku.update(techniques.BulkPencilMarking(sudoku).first().changes)
    assert renderers.plain(sudoku) == expected
Ejemplo n.º 5
0
def sudoku():
    return Sudoku.from_list(
        [
            [0, 0, 7, 0, 3, 0, 8, 0, 0],
            [0, 0, 0, 2, 0, 5, 0, 0, 0],
            [4, 0, 0, 9, 0, 6, 0, 0, 1],
            [0, 4, 3, 0, 0, 0, 2, 1, 0],
            [1, 0, 0, 0, 0, 0, 0, 0, 5],
            [0, 5, 8, 0, 0, 0, 6, 7, 0],
            [5, 0, 0, 1, 0, 8, 0, 0, 9],
            [0, 0, 0, 5, 0, 3, 0, 0, 0],
            [0, 0, 2, 0, 9, 0, 5, 0, 0],
        ],
        box_size=BoxSize(3, 3),
    )
Ejemplo n.º 6
0
def test_rank_sudoku_with_multiple_solutions():
    puzzle = [
        [8, 1, 0, 0, 0, 0, 6, 7, 9],
        [0, 0, 0, 6, 7, 9, 0, 2, 0],
        [0, 0, 0, 1, 2, 8, 3, 0, 0],
        [0, 3, 4, 0, 5, 7, 0, 0, 0],
        [2, 0, 0, 0, 0, 0, 7, 0, 4],
        [0, 0, 0, 0, 0, 6, 0, 0, 0],
        [0, 0, 3, 7, 0, 1, 0, 6, 2],
        [0, 0, 0, 0, 0, 0, 4, 0, 0],
        [0, 0, 1, 0, 3, 0, 0, 8, 0],
    ]
    sudoku = Sudoku.from_list(puzzle, box_size=BoxSize(3, 3))
    with pytest.raises(exceptions.MultipleSolutions):
        stats.rank(sudoku)
Ejemplo n.º 7
0
def test_colorful():
    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),
    )
    sudoku.update(techniques.BulkPencilMarking(sudoku).first().changes)
    assert "\033[93m2\033[0m" in renderers.colorful(sudoku)
Ejemplo n.º 8
0
def test_steps_raises_unsolvable():
    given = Sudoku.from_list(
        [
            [7, 0, 0, 0, 8, 2, 5, 0, 0],
            [0, 5, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 9, 0, 7, 0, 2, 6],
            [0, 0, 8, 0, 9, 0, 0, 7, 5],
            [3, 0, 0, 6, 7, 5, 0, 0, 0],
            [0, 0, 0, 0, 2, 0, 0, 9, 0],
            [9, 0, 1, 0, 0, 3, 0, 0, 0],
            [0, 0, 0, 0, 6, 0, 0, 0, 3],
            [6, 0, 2, 0, 0, 0, 0, 0, 0],
        ],
        box_size=BoxSize(3, 3),
    )

    with pytest.raises(exceptions.Unsolvable):
        list(solvers.steps(given))
Ejemplo n.º 9
0
def sudoku_12x12():
    return Sudoku.from_list(
        [
            [3, 0, 0, 9, 7, 4, 11, 1, 0, 6, 8, 12],
            [8, 0, 0, 6, 9, 2, 12, 0, 11, 4, 3, 0],
            [0, 0, 0, 4, 0, 3, 6, 5, 0, 2, 0, 10],
            [12, 5, 6, 1, 11, 10, 0, 0, 0, 9, 2, 3],
            [2, 8, 4, 10, 6, 0, 7, 3, 12, 0, 11, 5],
            [7, 11, 9, 3, 12, 0, 5, 0, 4, 0, 0, 6],
            [10, 4, 0, 7, 2, 11, 3, 0, 9, 0, 0, 0],
            [0, 9, 0, 0, 0, 0, 0, 12, 10, 0, 6, 0],
            [0, 3, 1, 12, 0, 8, 10, 9, 2, 7, 0, 11],
            [4, 0, 0, 0, 10, 0, 2, 7, 6, 0, 1, 9],
            [9, 2, 10, 0, 3, 0, 1, 0, 0, 0, 7, 0],
            [0, 6, 0, 11, 0, 12, 0, 0, 0, 0, 5, 2],
        ],
        box_size=BoxSize(3, 4),
    )
Ejemplo n.º 10
0
def test_bulk_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.BulkPencilMarking(sudoku).first()
    assert len(pencil_marks.changes) == 51
    assert len(list(techniques.BulkPencilMarking(sudoku))) == 1
Ejemplo n.º 11
0
def test_pencil_marking_all_board():
    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),
    )

    for step in techniques.PencilMarking(sudoku):
        sudoku.update(step.changes)

    assert sudoku.is_valid()
Ejemplo n.º 12
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})
    ]
Ejemplo n.º 13
0
def test_advanced_pencil_marking():
    sudoku = Sudoku.from_list(
        [
            [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(BulkPencilMarking(sudoku).first().changes)
    # there is a naked pair [7, 8] in the first row at (1, 3) and (1, 4)
    # replace {4, 6, 8} with {4, 8}
    sudoku[1, 1].candidates = {4, 8}

    pencil_marks = PencilMarking(sudoku).first()
    assert len(pencil_marks.changes) == 1
    assert pencil_marks.changes[0].candidates == {4, 6}
    assert pencil_marks.combination.cells == []
Ejemplo n.º 14
0
def make_sudoku_with_marks(puzzle: List[List[int]],
                           box_size: BoxSize) -> Sudoku:
    sudoku = Sudoku.from_list(puzzle, box_size=box_size)
    sudoku.update(techniques.BulkPencilMarking(sudoku).first().changes)
    return sudoku
Ejemplo n.º 15
0
def test_rank(puzzle, solutions, rank):
    sudoku = Sudoku.from_list(puzzle, box_size=BoxSize(3, 3))
    assert stats.rank(sudoku) == rank
Ejemplo n.º 16
0
def test_is_valid(puzzle, is_valid):
    sudoku = Sudoku.from_list(puzzle, box_size=BoxSize(3, 3))
    assert sudoku.is_valid() is is_valid
Ejemplo n.º 17
0
def test_is_solved_false(puzzle, solved):
    sudoku = Sudoku.from_list(puzzle, box_size=BoxSize(3, 3))
    assert sudoku.is_solved() is solved