Solve 2015:11 "Corporate Policy"

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.
This commit is contained in:
Anders Englöf Ytterström 2023-10-25 23:27:51 +02:00
parent 4742910afd
commit 838d06100b
2 changed files with 103 additions and 0 deletions

View file

@ -0,0 +1,68 @@
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()

View file

@ -0,0 +1,35 @@
import unittest
from solutions.day_11 import Solution
class Day11TestCase(unittest.TestCase):
def setUp(self):
self.solution = Solution()
self.puzzle_input = self.solution.parse_input(
"""
<REPLACE ME>
"""
)
def test_parse_puzzle_input(self):
data = """
<REPLACE ME>
""".strip()
assert self.solution.parse_input(data) == "<REPLACE ME>"
def test_validate_passwords(self):
assert not self.solution.is_valid("hijklmmn")
assert not self.solution.is_valid("abbceffg")
assert not self.solution.is_valid("abbcegjk")
def test_solve_first_part(self):
assert self.solution.solve("abcdefgh") == "abcdffaa"
assert self.solution.solve("ghijklmn") == "ghjaabcc"
# def test_solve_second_part(self):
# assert self.solution.solve_again(self.puzzle_input) == True
if __name__ == "__main__":
unittest.main()