コード例 #1
0
def steps(sudoku: Sudoku) -> Iterator[Step]:
    _sudoku = Sudoku(*sudoku.cells(), box_size=sudoku.box_size)

    all_techniques: Tuple[Type[Technique], ...] = (
        techniques.LoneSingle,
        techniques.HiddenSingle,
        techniques.NakedPair,
        techniques.NakedTriplet,
        techniques.LockedCandidate,
        techniques.XYWing,
        techniques.UniqueRectangle,
    )

    for step in techniques.BulkPencilMarking(_sudoku):
        _sudoku.update(step.changes)
        yield step

    while not _sudoku.is_solved():
        for technique in all_techniques:
            try:
                step = technique(_sudoku).first()
            except techniques.NotFound:
                continue
            else:
                _sudoku.update(step.changes)
                yield step
                break
        else:
            raise exceptions.Unsolvable
コード例 #2
0
 def _get_correct_cells(self) -> List[Cell]:
     sudoku = Sudoku(*[c for c in self.sudoku.cells() if c.value],
                     box_size=self.sudoku.box_size)
     all_techniques = (
         BulkPencilMarking,
         techniques.NakedPair,
         techniques.NakedTriplet,
         techniques.LockedCandidate,
         techniques.XYWing,
         techniques.UniqueRectangle,
     )
     for technique in all_techniques:
         for result in technique(sudoku):
             sudoku.update(result.changes)
     return [cell for cell in sudoku.cells() if cell.candidates]
コード例 #3
0
def eliminate(sudoku: Sudoku) -> Sudoku:
    _sudoku = Sudoku(*sudoku.cells(), box_size=sudoku.box_size)

    all_techniques = (
        techniques.LoneSingle,
        techniques.HiddenSingle,
    )

    for step in techniques.BulkPencilMarking(_sudoku):
        _sudoku.update(step.changes)

    has_result = True
    while has_result:
        for technique in all_techniques:
            has_result = False
            for step in technique(_sudoku):
                _sudoku.update(step.changes)
                has_result = True
    return _sudoku
コード例 #4
0
ファイル: stats.py プロジェクト: unmade/dokusan
def rank(sudoku: Sudoku) -> int:
    total_solutions = 0
    total_branch_factor = 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

    try:
        count(sudoku)
    except exceptions.NoCandidates:
        pass

    return (total_branch_factor * 100) + sum(1 for c in sudoku.cells() if not c.value)