From 10ae7a42bed7726f4186c30bb0cf6b01bb42db21 Mon Sep 17 00:00:00 2001 From: Daniel Lin Date: Sun, 3 Dec 2023 02:51:45 -0500 Subject: [PATCH] Day 3: Gear Ratios --- README.md | 2 +- py/aoc2023/day3.py | 56 ++++++++++++++++++++++++++++++++++++++++++++++ py/pyproject.toml | 1 + 3 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 py/aoc2023/day3.py diff --git a/README.md b/README.md index 94ce467e..a347b072 100644 --- a/README.md +++ b/README.md @@ -7,4 +7,4 @@ Development occurs in language-specific directories: |--:|--:|--:|--:| |[Day1.hs](hs/src/Day1.hs)|[Day1.kt](kt/aoc2023-lib/src/commonMain/kotlin/com/github/ephemient/aoc2023/Day1.kt)|[day1.py](py/aoc2023/day1.py)|[day1.rs](rs/src/day1.rs)| |[Day2.hs](hs/src/Day2.hs)|[Day2.kt](kt/aoc2023-lib/src/commonMain/kotlin/com/github/ephemient/aoc2023/Day2.kt)|[day2.py](py/aoc2023/day2.py)|[day2.rs](rs/src/day2.rs)| -|[Day3.hs](hs/src/Day3.hs)|[Day3.kt](kt/aoc2023-lib/src/commonMain/kotlin/com/github/ephemient/aoc2023/Day3.kt)||| +|[Day3.hs](hs/src/Day3.hs)|[Day3.kt](kt/aoc2023-lib/src/commonMain/kotlin/com/github/ephemient/aoc2023/Day3.kt)|[day3.py](py/aoc2023/day3.py)|| diff --git a/py/aoc2023/day3.py b/py/aoc2023/day3.py new file mode 100644 index 00000000..ab0b550a --- /dev/null +++ b/py/aoc2023/day3.py @@ -0,0 +1,56 @@ +""" +Day 3: Gear Ratios +""" + +import re +from collections import defaultdict +from math import prod + +SAMPLE_INPUT = """ +467..114.. +...*...... +..35..633. +......#... +617*...... +.....+.58. +..592..... +......755. +...$.*.... +.664.598.. +""" + +NUMBER_RE = re.compile(r"\d+") +SYMBOL_RE = re.compile(r"[^\s\d.]") + + +def _parse(data): + lines = data.splitlines() + for y, line in enumerate(lines): + for match in NUMBER_RE.finditer(line): + number = int(match.group(0)) + x0, x1 = match.span() + for yy in range(max(y - 1, 0), min(y + 2, len(lines))): + for match in SYMBOL_RE.finditer(lines[yy], x0 - 1, x1 + 1): + yield match.start(), yy, number + + +def part1(data): + """ + >>> part1(SAMPLE_INPUT) + 4361 + """ + return sum(number for _, _, number in _parse(data)) + + +def part2(data): + """ + >>> part2(SAMPLE_INPUT) + 467835 + """ + gears = defaultdict(list) + for x, y, number in _parse(data): + gears[x, y].append(number) + return sum(prod(numbers) for numbers in gears.values() if len(numbers) == 2) + + +parts = (part1, part2) diff --git a/py/pyproject.toml b/py/pyproject.toml index b94cddbc..778e9112 100644 --- a/py/pyproject.toml +++ b/py/pyproject.toml @@ -24,6 +24,7 @@ aoc2023 = "aoc2023.main:main" [tool.poetry.plugins."aoc2023.days"] day1 = "aoc2023.day1:parts" day2 = "aoc2023.day2:parts" +day3 = "aoc2023.day3:parts" [tool.black] target_version = ["py312"]