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:
parent
4742910afd
commit
838d06100b
2 changed files with 103 additions and 0 deletions
68
2015-python/solutions/day_11.py
Normal file
68
2015-python/solutions/day_11.py
Normal 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()
|
||||||
35
2015-python/tests/test_day_11.py
Normal file
35
2015-python/tests/test_day_11.py
Normal 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()
|
||||||
Loading…
Add table
Reference in a new issue