From c384d042233a8efd40ae1f08c4aef1de27e010e8 Mon Sep 17 00:00:00 2001 From: Christoph Stahl Date: Fri, 15 Dec 2023 10:13:44 +0100 Subject: [PATCH] Day 15 --- aoc/day15.py | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 aoc/day15.py diff --git a/aoc/day15.py b/aoc/day15.py new file mode 100644 index 0000000..8ebb440 --- /dev/null +++ b/aoc/day15.py @@ -0,0 +1,70 @@ +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()