70 lines
1.7 KiB
Python
70 lines
1.7 KiB
Python
from __future__ import annotations
|
|
from typing import Optional, TypeAlias
|
|
from dataclasses import dataclass, field
|
|
|
|
from .aoc import Aoc2
|
|
|
|
P1: TypeAlias = list[str]
|
|
P2: TypeAlias = list[tuple[str, Optional[int]]]
|
|
|
|
|
|
class Day15(Aoc2[P1, P2]):
|
|
def parseinput1(self, inpt: str) -> P1:
|
|
inpt = "".join(inpt.splitlines())
|
|
return inpt.split(",")
|
|
|
|
def parseinput2(self, inpt: str) -> P2:
|
|
inpt = "".join(inpt.splitlines())
|
|
|
|
output = []
|
|
for word in inpt.split(","):
|
|
if "-" in word:
|
|
output.append((word[:-1], None))
|
|
else:
|
|
name, boxnr = word.split("=")
|
|
output.append((name, int(boxnr)))
|
|
return output
|
|
|
|
@staticmethod
|
|
def hash(string: str) -> int:
|
|
waccum = 0
|
|
for char in string:
|
|
waccum += ord(char)
|
|
waccum *= 17
|
|
waccum = waccum % 256
|
|
return waccum
|
|
|
|
def part1(self, inpt: P1) -> int:
|
|
accum = 0
|
|
for word in inpt:
|
|
accum += self.hash(word)
|
|
return accum
|
|
|
|
def part2(self, inpt: P2) -> int:
|
|
boxes = {}
|
|
for name, op in inpt:
|
|
boxnr = self.hash(name)
|
|
if boxnr not in boxes:
|
|
boxes[boxnr] = {}
|
|
if op is None:
|
|
if name in boxes[boxnr]:
|
|
del boxes[boxnr][name]
|
|
else:
|
|
boxes[boxnr][name] = op
|
|
|
|
accum = 0
|
|
for nr, box in boxes.items():
|
|
for pos, (label, lens) in enumerate(box.items()):
|
|
fp = (1 + nr) * (1 + pos) * lens
|
|
accum += fp
|
|
|
|
return accum
|
|
|
|
|
|
def main() -> None:
|
|
aoc = Day15(2023, 15, example_code_nr2=0)
|
|
aoc.run()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|