|
| 1 | +"""Advent of Code 2023, Day 15: Lens Library.""" |
| 2 | + |
| 3 | +import sys |
| 4 | +from typing import TextIO |
| 5 | + |
| 6 | + |
| 7 | +def hash(step: str): |
| 8 | + value = 0 |
| 9 | + for c in step: |
| 10 | + value += ord(c) |
| 11 | + value *= 17 |
| 12 | + value %= 256 |
| 13 | + return value |
| 14 | + |
| 15 | + |
| 16 | +def index_of(items, predicate): |
| 17 | + return next((idx for idx, item in enumerate(items) if predicate(item)), -1) |
| 18 | + |
| 19 | + |
| 20 | +def part_one(file: TextIO) -> int: |
| 21 | + """Solve part one of the puzzle.""" |
| 22 | + steps = file.read().strip().split(",") |
| 23 | + return sum(map(hash, steps)) |
| 24 | + |
| 25 | + |
| 26 | +def part_two(file: TextIO) -> int: |
| 27 | + """Solve part two of the puzzle.""" |
| 28 | + steps = file.read().strip().split(",") |
| 29 | + boxes = {i: [] for i in range(256)} |
| 30 | + for step in steps: |
| 31 | + if "-" in step: |
| 32 | + label = step[:-1] |
| 33 | + i = hash(label) |
| 34 | + if (idx := index_of(boxes[i], lambda item: label in item)) >= 0: |
| 35 | + boxes[i].pop(idx) |
| 36 | + if "=" in step: |
| 37 | + label = step[:-2] |
| 38 | + i = hash(label) |
| 39 | + if (idx := index_of(boxes[i], lambda item: label in item)) >= 0: |
| 40 | + boxes[i].pop(idx) |
| 41 | + boxes[i].insert(idx, step) |
| 42 | + else: |
| 43 | + boxes[i].append(step) |
| 44 | + |
| 45 | + def box_value(box: int) -> int: |
| 46 | + return (box + 1) * sum((i + 1) * int(item[-1]) for i, item in enumerate(boxes[box])) |
| 47 | + |
| 48 | + return sum(map(box_value, boxes.keys())) |
| 49 | + |
| 50 | + |
| 51 | +def main(): |
| 52 | + """The main entrypoint for the script.""" |
| 53 | + filename = sys.argv[0].replace(".py", ".txt") |
| 54 | + |
| 55 | + with open(filename, encoding="utf-8") as file: |
| 56 | + print("Part one:", part_one(file)) |
| 57 | + |
| 58 | + with open(filename, encoding="utf-8") as file: |
| 59 | + print("Part two:", part_two(file)) |
| 60 | + |
| 61 | + |
| 62 | +if __name__ == "__main__": |
| 63 | + main() |
0 commit comments