From 6145f6b9eeee21977ead96cbe66bf8723e61cb6a Mon Sep 17 00:00:00 2001 From: Pavel Karateev Date: Sun, 7 Jan 2024 19:45:12 +0100 Subject: [PATCH] 2023 day 15 part 2 --- README.md | 2 +- src/year2023/day15b.py | 41 +++++++++++++++++++++++++++++++ tests/src/year2023/test_day15b.py | 13 ++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 src/year2023/day15b.py create mode 100644 tests/src/year2023/test_day15b.py diff --git a/README.md b/README.md index a4fb627..608aba6 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ - 2020 - ★★★★★ ★★★★★ ★★★★★ ☆ - 2021 - ★★★★★ ★★★★★ ★★★★★ ★★★ - 2022 - ★★★★★ ★★★★★ ★★★★★ ★☆ -- 2023 - ★★★★☆ ★☆★★☆ ★★☆★☆ +- 2023 - ★★★★☆ ★☆★★☆ ★★☆★★ ## How to use diff --git a/src/year2023/day15b.py b/src/year2023/day15b.py new file mode 100644 index 0000000..6193eb4 --- /dev/null +++ b/src/year2023/day15b.py @@ -0,0 +1,41 @@ +"""2023 - Day 15 Part 2: Lens Library""" +import re +from collections import defaultdict +from typing import TypeAlias + +from src.year2023.day15a import get_hash + +Boxes: TypeAlias = dict[int, dict[str, int]] + + +def parse_task(task: str) -> Boxes: + boxes: Boxes = defaultdict(dict) + + for step in task.split(","): + [(label, op, focal)] = re.findall(r"([a-z]+)([=\-])(\d+)?", step) + box = get_hash(label) + + if op == "=": + boxes[box][label] = int(focal) + elif op == "-": + if label in boxes[box]: + del boxes[box][label] + else: + raise ValueError(f"unknown op: {op}") + + return boxes + + +def get_focus_power(boxes: Boxes) -> int: + total = 0 + + for box in range(256): + for slot, (_, focal) in enumerate(boxes[box].items(), start=1): + total += (box + 1) * slot * focal + + return total + + +def solve(task: str) -> int: + boxes = parse_task(task) + return get_focus_power(boxes) diff --git a/tests/src/year2023/test_day15b.py b/tests/src/year2023/test_day15b.py new file mode 100644 index 0000000..7eb89d8 --- /dev/null +++ b/tests/src/year2023/test_day15b.py @@ -0,0 +1,13 @@ +"""2023 - Day 15 Part 2: Lens Library""" +from textwrap import dedent + +from src.year2023.day15b import solve + + +def test_solve(): + task = dedent( + """ + rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7 + """ + ).strip() + assert solve(task) == 145