advent-of-code/src/holt59/aoc/2015/day11.py
Mikaël Capelle ce315b8778 Refactor code for API (#3)
Co-authored-by: Mikael CAPELLE <mikael.capelle@thalesaleniaspace.com>
Co-authored-by: Mikaël Capelle <capelle.mikael@gmail.com>
Reviewed-on: #3
2024-12-08 13:06:41 +00:00

50 lines
1.1 KiB
Python

import itertools
from typing import Any, Iterator
from ..base import BaseSolver
def is_valid(p: str) -> bool:
if any(c in "iol" for c in p):
return False
if not any(
ord(a) + 1 == ord(b) and ord(b) + 1 == ord(c)
for a, b, c in zip(p, p[1:], p[2:])
):
return False
if sum(len(list(g)) >= 2 for _, g in itertools.groupby(p)) < 2:
return False
return True
assert not is_valid("hijklmmn")
assert not is_valid("abbceffg")
assert not is_valid("abbcegjk")
assert is_valid("abcdffaa")
assert is_valid("ghjaabcc")
def increment(p: str) -> str:
if p[-1] == "z":
return increment(p[:-1]) + "a"
elif p[-1] in "iol":
return p[:-1] + chr(ord(p[-1]) + 2)
else:
return p[:-1] + chr(ord(p[-1]) + 1)
def find_next_password(p: str) -> str:
while not is_valid(p):
p = increment(p)
return p
class Solver(BaseSolver):
def solve(self, input: str) -> Iterator[Any]:
answer_1 = find_next_password(input)
yield answer_1
yield find_next_password(increment(answer_1))