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