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.
This commit is contained in:
Anders Englöf Ytterström 2024-12-08 09:43:22 +01:00
parent 63da79b2a4
commit e75670eaf2

View file

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