2016-12-04 - Security Through Obscurity
(original .ipynb)
from collections import defaultdict
puzzle_input_str = open("puzzle_input/day4.txt").read()
test_input_str = """aaaaa-bbb-z-y-x-123[abxyz]
a-b-c-d-e-f-g-h-987[abcde]
not-a-real-room-404[oarel]
totally-real-room-200[decoy]"""
def most_common_letters(name_parts):
counts = defaultdict(lambda:0)
for c in "".join(name_parts):
counts[c] += 1
return list(sorted(counts.items(), key=lambda x:(-x[1], x[0])))[:5]
def part_one(input_str):
count = 0
for line in input_str.split("\n"):
line_parts = line.split("-")
encrypted_name_parts = line_parts[:-1]
sector_and_checksum = line_parts[-1].split("[")
sector_id = int(sector_and_checksum[0])
checksum = sector_and_checksum[1].removesuffix("]")
if all(letter in checksum for letter,_ in most_common_letters(encrypted_name_parts)):
count += sector_id
return count
assert 1514 == part_one(test_input_str)
print("part one:", part_one(puzzle_input_str))
part one: 158835
def rotate(letter, sector_id):
a = ord("a")
l = ord(letter) - a
return chr(a + ((l + sector_id) % 26))
def decrypt(enc_name, sector_id):
name = []
for l in enc_name:
name.append(rotate(l, sector_id))
return "".join(name)
def part_two(input_str):
count = 0
for line in input_str.split("\n"):
line_parts = line.split("-")
encrypted_name_parts = line_parts[:-1]
sector_and_checksum = line_parts[-1].split("[")
sector_id = int(sector_and_checksum[0])
checksum = sector_and_checksum[1].removesuffix("]")
if all(letter in checksum for letter,_ in most_common_letters(encrypted_name_parts)):
name = " ".join(decrypt(part, sector_id) for part in encrypted_name_parts)
if "north" in name.lower():
return sector_id
raise Exception("something is not quite right")
assert "very encrypted name" == " ".join(decrypt_name(part, 343) for part in ["qzmt","zixmtkozy","ivhz"])
print("part two:", part_two(puzzle_input_str))
part two: 993