From 22ef615c91f2a259e30210e433c51063172a18d5 Mon Sep 17 00:00:00 2001 From: Daniel Lin Date: Mon, 2 Dec 2024 01:34:04 -0500 Subject: [PATCH] Day 2: Red-Nosed Reports --- README.md | 2 +- py/aoc2024/day2.py | 68 ++++++++++++++++++++++++++++++++++++++++++++++ py/pyproject.toml | 1 + 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 py/aoc2024/day2.py diff --git a/README.md b/README.md index 9eb7522..3719efd 100644 --- a/README.md +++ b/README.md @@ -6,4 +6,4 @@ Development occurs in language-specific directories: |[Haskell](hs) ![Haskell CI](https://github.com/ephemient/aoc2024/workflows/Haskell%20CI/badge.svg)|[Kotlin](kt) ![Kotlin CI](https://github.com/ephemient/aoc2024/workflows/Kotlin%20CI/badge.svg)|[Python](py) ![Python CI](https://github.com/ephemient/aoc2024/workflows/Python%20CI/badge.svg)|[Rust](rs) ![Rust CI](https://github.com/ephemient/aoc2024/workflows/Rust%20CI/badge.svg)| |--:|--:|--:|--:| |[Day1.hs](hs/src/Day1.hs)|[Day1.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day1.kt)|[day1.py](py/aoc2024/day1.py)|[day1.rs](rs/src/day1.rs)| -|[Day2.hs](hs/src/Day2.hs)|[Day2.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day2.kt)||| +|[Day2.hs](hs/src/Day2.hs)|[Day2.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day2.kt)|[day2.py](py/aoc2024/day2.py)|| diff --git a/py/aoc2024/day2.py b/py/aoc2024/day2.py new file mode 100644 index 0000000..0846946 --- /dev/null +++ b/py/aoc2024/day2.py @@ -0,0 +1,68 @@ +""" +Day 2: Red-Nosed Reports +""" + +from typing import Generator + +SAMPLE_INPUT = """ +7 6 4 2 1 +1 2 7 8 9 +9 7 6 2 1 +1 3 2 4 5 +8 6 4 4 1 +1 3 6 7 9 +""" + + +def _parse(data: str) -> Generator[list[int]]: + for line in data.splitlines(): + line = line.strip() + if line: + yield [int(level) for level in line.split()] + + +def _issafe1(report: list[int]) -> bool: + decreasing, increasing = False, False + for x, y in zip(report, report[1:]): + delta = x - y + if -3 <= delta <= -1: + decreasing = True + if increasing: + break + elif 1 <= delta <= 3: + increasing = True + if decreasing: + break + else: + break + else: + return True + return False + + +def _issafe2(report: list[int]) -> bool: + report2 = report[:-1].copy() + for i in range(len(report2), 0, -1): + if _issafe1(report2): + return True + report2[i - 1] = report[i] + return _issafe1(report2) + + +def part1(data: str) -> int: + """ + >>> part1(SAMPLE_INPUT) + 2 + """ + return sum(map(_issafe1, _parse(data))) + + +def part2(data) -> int: + """ + >>> part2(SAMPLE_INPUT) + 4 + """ + return sum(map(_issafe2, _parse(data))) + + +parts = (part1, part2) diff --git a/py/pyproject.toml b/py/pyproject.toml index a121a04..0515cf6 100644 --- a/py/pyproject.toml +++ b/py/pyproject.toml @@ -25,6 +25,7 @@ aoc2024 = "aoc2024.main:main" [tool.poetry.plugins."aoc2024.days"] day1 = "aoc2024.day1:parts" +day2 = "aoc2024.day2:parts" [build-system] requires = ["poetry-core"]