I brainfarted and had a hard time trying to understand the instructions. > Incrementing is just like counting with numbers: xx, xy, xz, ya, yb, and so on. Increase the rightmost letter one step; if it was z, it wraps around to a, and repeat with the next letter to the left until one doesn't wrap around. I only managed to understand it by looking at solutions on the subreddit, figuring out the correct behavior: az -> ba, azzz -> baaa, azzzzz -> baaaaa etc. I also sped up the test case containing `ghi` as initial password, by looking for the leftmost invalid I, L or O and increase it, replacing all following chars with `a`. ghijklmn -> ghjaaaaa.
68 lines
1.8 KiB
Python
68 lines
1.8 KiB
Python
import re
|
|
from solutions import BaseSolution
|
|
|
|
|
|
class Solution(BaseSolution):
|
|
input_file = "11.txt"
|
|
|
|
def __str__(self):
|
|
return "Day 11: Corporate Policy"
|
|
|
|
def is_valid(self, suggestion):
|
|
if "i" in suggestion or "l" in suggestion or "o" in suggestion:
|
|
return False
|
|
if (
|
|
len(
|
|
set(
|
|
map(
|
|
lambda x: x[0],
|
|
filter(lambda x: x[0] == x[1], zip(suggestion, suggestion[1:])),
|
|
)
|
|
)
|
|
)
|
|
< 2
|
|
):
|
|
return False
|
|
|
|
def seq(abc):
|
|
a, b, c = abc
|
|
return ord(b) - ord(a) == 1 and ord(c) - ord(b) == 1
|
|
|
|
return any(map(seq, zip(suggestion, suggestion[1:], suggestion[2:])))
|
|
|
|
def parse_input(self, data):
|
|
return data
|
|
|
|
def solve(self, password):
|
|
def tick(p):
|
|
chars = list(p)[::-1]
|
|
i = 0
|
|
for c in chars:
|
|
if c == "z":
|
|
chars[i] = "a"
|
|
else:
|
|
chars[i] = chr(ord(chars[i]) + 1)
|
|
break
|
|
i += 1
|
|
return "".join(chars[::-1])
|
|
|
|
unallowed = re.compile(r"i|l|o")
|
|
fastforward = re.search(unallowed, password)
|
|
if fastforward:
|
|
password = (
|
|
password[: fastforward.start()]
|
|
+ chr(ord(password[fastforward.start()]) + 1)
|
|
).ljust(len(password), "a")
|
|
|
|
while True:
|
|
password = tick(password)
|
|
if self.is_valid(password):
|
|
return password
|
|
|
|
def solve_again(self, puzzle_input):
|
|
return self.solve(self.solve(puzzle_input))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
solution = Solution()
|
|
solution.show_results()
|