From a1db2a4adfc72b76548db83395adcbdd8189ffd2 Mon Sep 17 00:00:00 2001 From: Nettika Date: Mon, 2 Dec 2024 00:43:39 -0800 Subject: [PATCH] Implement day 2 solver --- puzzles/2.py | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 2 +- 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 puzzles/2.py diff --git a/puzzles/2.py b/puzzles/2.py new file mode 100644 index 0000000..4bff707 --- /dev/null +++ b/puzzles/2.py @@ -0,0 +1,62 @@ +from itertools import islice +from typing import Iterator +from more_itertools import ilen + +test_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 +""".strip() + +test_solution_p1 = 2 +test_solution_p2 = 4 + + +def solve_p1(puzzle_input: str) -> int: + reports = _parse_reports(puzzle_input) + delta_reports = (_deltas(report) for report in reports) + safe_delta_reports = filter(_is_gradual_monotonic, delta_reports) + return ilen(safe_delta_reports) + + +def solve_p2(puzzle_input: str) -> int: + reports = _parse_reports(puzzle_input) + dampened_report_collections = (_dampen_permutations(report) for report in reports) + delta_report_collections = ( + (_deltas(report) for report in report_collection) + for report_collection in dampened_report_collections + ) + safe_report_collections = filter( + lambda delta_report_collection: any( + _is_gradual_monotonic(delta_report) + for delta_report in delta_report_collection + ), + delta_report_collections, + ) + return ilen(safe_report_collections) + + +def _parse_reports(puzzle_input: str) -> Iterator[tuple[int, ...]]: + lines = puzzle_input.splitlines() + return (tuple(int(level) for level in line.split(" ")) for line in lines) + + +def _deltas(report: tuple[int, ...]) -> tuple[int, ...]: + pairs = zip(report, islice(report, 1, None)) + return tuple(b - a for a, b in pairs) + + +def _is_gradual_monotonic(delta_report: tuple[int]) -> bool: + sign = 1 if delta_report[0] > 0 else -1 + return all( + delta != 0 and delta / abs(delta) == sign and abs(delta) < 4 + for delta in delta_report + ) + + +def _dampen_permutations(report: tuple[int, ...]) -> Iterator[tuple[int, ...]]: + yield report + yield from (report[:i] + report[i + 1 :] for i in range(0, len(report))) diff --git a/pyproject.toml b/pyproject.toml index 143b244..91a43bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,4 +2,4 @@ name = "advent-of-code-2024" version = "0.0.0" description = "Advent of Code 2024" -dependencies = ["advent"] +dependencies = ["advent", "more-itertools"]