make helpers operate on seqs; documentation

This commit is contained in:
Jörn-Michael Miehe 2023-08-20 11:41:07 +00:00
parent 1181e96ab3
commit ae3490f478
3 changed files with 33 additions and 23 deletions
pigeon_magnet_solver
tests

View file

@ -1,4 +1,5 @@
from dataclasses import dataclass from dataclasses import dataclass
from typing import Self
from .helpers import rotate_r from .helpers import rotate_r
@ -10,7 +11,7 @@ class Board:
@classmethod @classmethod
@property @property
def default_puzzle(cls) -> "Board": def default_puzzle(cls) -> Self:
return cls( return cls(
rows=["011", "011", "100", "x1x"], rows=["011", "011", "100", "x1x"],
buttons=(3, 4, 5, 7), buttons=(3, 4, 5, 7),
@ -98,6 +99,7 @@ class Board:
row, col = index // self.width, index % self.width row, col = index // self.width, index % self.width
assert self.rows[row][col] == "1", f"{index} is not clickable!" assert self.rows[row][col] == "1", f"{index} is not clickable!"
# get neighbor positions
nb_rc = [ nb_rc = [
(row - 1, col), (row - 1, col),
(row, col + 1), (row, col + 1),
@ -105,7 +107,9 @@ class Board:
(row, col - 1), (row, col - 1),
] ]
nb_str = "".join(self[*rc] for rc in nb_rc) # rotate neighbors
nb_rot = rotate_r([self[rc] for rc in nb_rc])
for rc, val in zip(nb_rc, rotate_r(nb_str)): # set new neighbors
for rc, val in zip(nb_rc, nb_rot):
self[rc] = val self[rc] = val

View file

@ -1,8 +1,13 @@
def _rotate_r(__s: str) -> str: from typing import Iterable, TypeVar
return __s[-1] + __s[0:-1]
T = TypeVar("T")
def _valid_rotate(__s: str, __c: str) -> bool: def _rotate_r(__s: list[T]) -> list[T]:
return [__s[-1]] + __s[0:-1]
def _valid_rotate(__s: Iterable[str], __c: Iterable[str]) -> bool:
for sc, cc in zip(__s, __c): for sc, cc in zip(__s, __c):
# can never rotate a "1" onto an "x" # can never rotate a "1" onto an "x"
if sc == "x" and cc == "1": if sc == "x" and cc == "1":
@ -11,23 +16,23 @@ def _valid_rotate(__s: str, __c: str) -> bool:
return True return True
def _fix_exes(__s: str, __c: str) -> str: def _fix_exes(__s: Iterable[str], __c: Iterable[str]) -> list[str]:
result = "" result = []
for sc, cc in zip(__s, __c): for sc, cc in zip(__s, __c):
if sc == "x": if sc == "x":
result += "x" result.append("x")
elif cc == "x": elif cc == "x":
result += "0" result.append("0")
else: else:
result += cc result.append(cc)
return result return result
def rotate_r(__s: str) -> str: def rotate_r(__s: list[str]) -> list[str]:
result = _rotate_r(__s) result = _rotate_r(__s)
while not _valid_rotate(__s, result): while not _valid_rotate(__s, result):

View file

@ -1,17 +1,18 @@
from pigeon_magnet_solver import helpers from pigeon_magnet_solver.helpers import (_fix_exes, _rotate_r, _valid_rotate,
rotate_r)
def test_rotate_r(): def test_rotate_r():
assert helpers._rotate_r("1x01") == "11x0" assert _rotate_r(list("1x01")) == list("11x0")
assert helpers._rotate_r("11x0") == "011x" assert _rotate_r(list("11x0")) == list("011x")
assert helpers._rotate_r("011x") == "x011" assert _rotate_r(list("011x")) == list("x011")
assert helpers._rotate_r("x011") == "1x01" assert _rotate_r(list("x011")) == list("1x01")
assert helpers._valid_rotate("1x01", "11x0") is False assert _valid_rotate(list("1x01"), list("11x0")) is False
assert helpers._valid_rotate("1x01", "011x") is False assert _valid_rotate(list("1x01"), list("011x")) is False
assert helpers._valid_rotate("1x01", "x011") is True assert _valid_rotate(list("1x01"), list("x011")) is True
assert helpers._valid_rotate("1x01", "1x01") is True assert _valid_rotate(list("1x01"), list("1x01")) is True
assert helpers._fix_exes("1x01", "x011") == "0x11" assert _fix_exes(list("1x01"), list("x011")) == list("0x11")
assert helpers.rotate_r("1x01") == "0x11" assert rotate_r(list("1x01")) == list("0x11")