Module sudoku.strategies.naked_subset¶
None
None
View Source
from __future__ import annotations
from typing import TYPE_CHECKING
from .strategy import Strategy
if TYPE_CHECKING:
from ..puzzle import Puzzle, T
class NakedSubset(Strategy):
"""
Apply the [Naked Subset](http://sudopedia.enjoysudoku.com/Naked_Subset.html) strategy
"""
__slots__ = ("size",)
def __init__(self, size: int):
super().__init__(difficulty=0.323 * size)
self.name += f" - {size}"
self.size = size
def __call__(self, puzzle: Puzzle[T]) -> int:
if self.size <= 0 or self.size >= puzzle.order:
return 0
complement_size = puzzle.order - self.size
if complement_size < self.size:
from .hidden_subset import HiddenSubset
return HiddenSubset(complement_size)(puzzle)
candidate_eliminations = 0
for b, blank in puzzle._blank():
if len(blank.candidates) == self.size:
for house in [puzzle._row, puzzle._col, puzzle._box]:
complement = set(
p
for p, peer in house(b)
if (
len(peer.candidates) > self.size
or any((pc not in blank.candidates) for pc in peer.candidates)
)
)
if len(complement) == complement_size:
for p in complement:
for c in blank.candidates:
if c in puzzle.cells[p].candidates:
puzzle.cells[p].candidates.remove(c)
candidate_eliminations += 1
return candidate_eliminations
class NakedSingle(NakedSubset):
"""
The [Naked Single](http://sudopedia.enjoysudoku.com/Naked_Single.html) strategy
"""
def __init__(self):
super().__init__(1)
class ForcedDigit(NakedSingle):
"""
Alias for the [[NakedSingle]] strategy
"""
class SoleCandidate(NakedSingle):
"""
Alias for the [[NakedSingle]] strategy
"""
class NakedDouble(NakedSubset):
"""
Apply the [Naked Double](http://sudopedia.enjoysudoku.com/Naked_Double.html) strategy
"""
def __init__(self):
super().__init__(2)
class NakedTriple(NakedSubset):
"""
Apply the [Naked Triple](http://sudopedia.enjoysudoku.com/Naked_Triple.html) strategy
"""
def __init__(self):
super().__init__(3)
class NakedQuad(NakedSubset):
"""
Apply the [Naked Quad](http://sudopedia.enjoysudoku.com/Naked_Quad.html) strategy
"""
def __init__(self):
super().__init__(4)
__all__ = ("ForcedDigit", "NakedDouble", "NakedQuad", "NakedSingle", "NakedSubset", "NakedTriple")
Classes¶
ForcedDigit¶
1 2 3 |
|
View Source
class ForcedDigit(NakedSingle):
"""
Alias for the [[NakedSingle]] strategy
"""
Ancestors (in MRO)¶
- sudoku.strategies.naked_subset.NakedSingle
- sudoku.strategies.naked_subset.NakedSubset
- sudoku.strategies.strategy.Strategy
Class variables¶
1 |
|
1 |
|
Instance variables¶
1 |
|
NakedDouble¶
1 2 3 |
|
View Source
class NakedDouble(NakedSubset):
"""
Apply the [Naked Double](http://sudopedia.enjoysudoku.com/Naked_Double.html) strategy
"""
def __init__(self):
super().__init__(2)
Ancestors (in MRO)¶
- sudoku.strategies.naked_subset.NakedSubset
- sudoku.strategies.strategy.Strategy
Class variables¶
1 |
|
1 |
|
Instance variables¶
1 |
|
NakedQuad¶
1 2 3 |
|
View Source
class NakedQuad(NakedSubset):
"""
Apply the [Naked Quad](http://sudopedia.enjoysudoku.com/Naked_Quad.html) strategy
"""
def __init__(self):
super().__init__(4)
Ancestors (in MRO)¶
- sudoku.strategies.naked_subset.NakedSubset
- sudoku.strategies.strategy.Strategy
Class variables¶
1 |
|
1 |
|
Instance variables¶
1 |
|
NakedSingle¶
1 2 3 |
|
View Source
class NakedSingle(NakedSubset):
"""
The [Naked Single](http://sudopedia.enjoysudoku.com/Naked_Single.html) strategy
"""
def __init__(self):
super().__init__(1)
Ancestors (in MRO)¶
- sudoku.strategies.naked_subset.NakedSubset
- sudoku.strategies.strategy.Strategy
Descendants¶
- sudoku.strategies.naked_subset.ForcedDigit
- sudoku.strategies.naked_subset.SoleCandidate
Class variables¶
1 |
|
1 |
|
Instance variables¶
1 |
|
NakedSubset¶
1 2 3 |
|
View Source
class NakedSubset(Strategy):
"""
Apply the [Naked Subset](http://sudopedia.enjoysudoku.com/Naked_Subset.html) strategy
"""
__slots__ = ("size",)
def __init__(self, size: int):
super().__init__(difficulty=0.323 * size)
self.name += f" - {size}"
self.size = size
def __call__(self, puzzle: Puzzle[T]) -> int:
if self.size <= 0 or self.size >= puzzle.order:
return 0
complement_size = puzzle.order - self.size
if complement_size < self.size:
from .hidden_subset import HiddenSubset
return HiddenSubset(complement_size)(puzzle)
candidate_eliminations = 0
for b, blank in puzzle._blank():
if len(blank.candidates) == self.size:
for house in [puzzle._row, puzzle._col, puzzle._box]:
complement = set(
p
for p, peer in house(b)
if (
len(peer.candidates) > self.size
or any((pc not in blank.candidates) for pc in peer.candidates)
)
)
if len(complement) == complement_size:
for p in complement:
for c in blank.candidates:
if c in puzzle.cells[p].candidates:
puzzle.cells[p].candidates.remove(c)
candidate_eliminations += 1
return candidate_eliminations
Ancestors (in MRO)¶
- sudoku.strategies.strategy.Strategy
Descendants¶
- sudoku.strategies.naked_subset.NakedSingle
- sudoku.strategies.naked_subset.NakedDouble
- sudoku.strategies.naked_subset.NakedTriple
- sudoku.strategies.naked_subset.NakedQuad
Class variables¶
1 |
|
1 |
|
Instance variables¶
1 |
|
NakedTriple¶
1 2 3 |
|
View Source
class NakedTriple(NakedSubset):
"""
Apply the [Naked Triple](http://sudopedia.enjoysudoku.com/Naked_Triple.html) strategy
"""
def __init__(self):
super().__init__(3)
Ancestors (in MRO)¶
- sudoku.strategies.naked_subset.NakedSubset
- sudoku.strategies.strategy.Strategy
Class variables¶
1 |
|
1 |
|
Instance variables¶
1 |
|