advent-of-code/2016-python2/output/day_21.py
Anders Englöf Ytterström e75670eaf2 Solve 2016:21 p1-2 "Scrambled Letters and Hash"
A good day to utilize lots of unit testing!

For pt 2, the code initially tried to reverse
the scramble algorithm. The final code however
got the unscrambled version by the traditional
method most password crackers would resolve to:
basic brute forcing with permutations as a list
of candidates.
2024-12-12 13:53:43 +01:00

64 lines
2 KiB
Python

import re
from itertools import permutations
from output import ints
def solve(data):
data = [line.strip() for line in data.splitlines()]
p1 = scramble(data, "abcdefgh")
p2 = unscramble(data, "fbgdceah")
return p1, p2
def scramble(data, subject):
r_swap = r"(?:letter|position) (.)"
for line in data:
if line.startswith("rotate right"):
x = ints(line)[0]
subject = subject[-x:] + subject[:-x]
if line.startswith("rotate left"):
x = ints(line)[0]
subject = subject[x:] + subject[:x]
if line.startswith("rotate based"):
x = re.findall(r"letter (.)", line)[0]
i = subject.index(x)
j = i + 1 % len(subject)
subject = subject[-j:] + subject[:-j]
if i >= 4:
subject = subject[-1:] + subject[:-1]
if line.startswith("swap letter"):
x, y = re.findall(r_swap, line)
subject = subject.replace(y, "#")
subject = subject.replace(x, y)
subject = subject.replace("#", x)
if line.startswith("swap position"):
x, y = ints(line)
v1, v2 = subject[x], subject[y]
subject = subject[:x] + v2 + subject[x + 1 :]
subject = subject[:y] + v1 + subject[y + 1 :]
if line.startswith("move"):
x, y = ints(line)
v = subject[x]
subject = subject[:x] + subject[x + 1 :]
subject = subject[:y] + v + subject[y:]
if line.startswith("reverse"):
x, y = ints(line)
subject = subject[:x] + subject[x : y + 1][::-1] + subject[y + 1 :]
return subject
def unscramble(data, T):
for candidate in ["".join(c) for c in permutations(T)]:
if scramble(data, candidate) == T:
return candidate
if __name__ == "__main__":
with open("./input/21.txt", "r") as f:
inp = f.read().strip()
p1, p2 = solve(inp)
print(p1)
print(p2)