[py] Port 2016_04, kinda
This commit is contained in:
parent
c8f033b32f
commit
2038c5ccde
5 changed files with 85 additions and 420 deletions
|
|
@ -2,7 +2,7 @@ import sys
|
|||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
from .y2016 import d01, d02, d03
|
||||
from .y2016 import d01, d02, d03, d04
|
||||
from .y2017 import d01, d02, d03, d04, d05, d06, d07, d08, d09
|
||||
from .y2018 import d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11
|
||||
from .y2020 import d10
|
||||
|
|
@ -13,6 +13,7 @@ DAYS = {
|
|||
"2016_01": y2016.d01.solve,
|
||||
"2016_02": y2016.d02.solve,
|
||||
"2016_03": y2016.d03.solve,
|
||||
"2016_04": y2016.d04.solve,
|
||||
"2017_01": y2017.d01.solve,
|
||||
"2017_02": y2017.d02.solve,
|
||||
"2017_03": y2017.d03.solve,
|
||||
|
|
|
|||
83
py/aoc/y2016/d04.py
Normal file
83
py/aoc/y2016/d04.py
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
import re
|
||||
|
||||
# PART 1
|
||||
|
||||
ROOM_RE = r"(.*)-(\d+)\[(.{5})\]"
|
||||
|
||||
|
||||
def load_rooms(inputstr):
|
||||
rooms = []
|
||||
for line in inputstr.splitlines():
|
||||
match = re.fullmatch(ROOM_RE, line)
|
||||
name, sector, checksum = match.groups()
|
||||
name = name.split("-")
|
||||
sector = int(sector)
|
||||
rooms.append((name, sector, checksum))
|
||||
return rooms
|
||||
|
||||
|
||||
def checksum(name):
|
||||
name = "".join(name)
|
||||
freqs = {}
|
||||
for char in name:
|
||||
freqs[char] = freqs.get(char, 0) + 1
|
||||
|
||||
top = freqs.items()
|
||||
top = sorted(top, key=lambda x: x[0])
|
||||
top = sorted(top, key=lambda x: x[1], reverse=True)
|
||||
top = list(top)[:5]
|
||||
top = map(lambda x: x[0], top)
|
||||
return "".join(top)
|
||||
|
||||
|
||||
def sum_correct_sectors(rooms):
|
||||
total = 0
|
||||
for name, sector, chk in rooms:
|
||||
if checksum(name) == chk:
|
||||
total += sector
|
||||
return total
|
||||
|
||||
|
||||
# PART 2
|
||||
|
||||
|
||||
def shift(s):
|
||||
new_s = []
|
||||
for c in s:
|
||||
if ord("a") <= ord(c) <= ord("z"):
|
||||
new_c = chr(
|
||||
ord("a") + ((ord(c) - ord("a") + 1) % (ord("z") - ord("a") + 1))
|
||||
)
|
||||
new_s.append(new_c)
|
||||
elif ord("A") <= ord(c) <= ord("Z"):
|
||||
new_c = chr(
|
||||
ord("A") + ((ord(c) - ord("A") + 1) % (ord("Z") - ord("A") + 1))
|
||||
)
|
||||
new_s.append(new_c)
|
||||
else:
|
||||
new_s.append("?")
|
||||
return "".join(new_s)
|
||||
|
||||
|
||||
def decrypt_name(name, sector):
|
||||
for _ in range(sector % 26):
|
||||
name = map(shift, name)
|
||||
return " ".join(name)
|
||||
|
||||
|
||||
def decrypt_names(rooms, filename):
|
||||
with open(filename, "w") as f:
|
||||
for name, sector, chk in rooms:
|
||||
if checksum(name) == chk:
|
||||
name = decrypt_name(name, sector)
|
||||
line = f"{name}-{sector}[{chk}]\n"
|
||||
f.write(line)
|
||||
|
||||
|
||||
def solve(inputstr):
|
||||
rooms = load_rooms(inputstr)
|
||||
total = sum_correct_sectors(rooms)
|
||||
print(f"Part 1: {total}")
|
||||
# filename_2 = inputstr + ".decrypted"
|
||||
# decrypt_names(rooms, filename_2)
|
||||
# print(f"Part 2: see {filename_2} (search for 'northpole object storage')")
|
||||
Loading…
Add table
Add a link
Reference in a new issue