From 3375d25b92492b99d8edf383b97ca881f6f7ab75 Mon Sep 17 00:00:00 2001 From: Nettika Date: Wed, 20 Dec 2023 20:58:01 -0800 Subject: [PATCH] Solve day 9 --- advent_of_code/__init__.py | 3 ++- advent_of_code/oasis.py | 28 +++++++++++++++++++++++ tests/oasis_test.py | 46 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 advent_of_code/oasis.py create mode 100644 tests/oasis_test.py diff --git a/advent_of_code/__init__.py b/advent_of_code/__init__.py index b630c26..dc3e813 100644 --- a/advent_of_code/__init__.py +++ b/advent_of_code/__init__.py @@ -5,7 +5,7 @@ __version__ = "1.0.0" from typing import Callable -from advent_of_code import cubes, gears, network, scratchcards, trebuchet +from advent_of_code import cubes, gears, network, oasis, scratchcards, trebuchet Solver = Callable[[str], int] @@ -16,4 +16,5 @@ solvers: dict[int, tuple[Solver, Solver]] = { 3: (gears.solve_part_1, gears.solve_part_2), 4: (scratchcards.solve_part_1, scratchcards.solve_part_2), 8: (network.solve_part_1, network.solve_part_2), + 9: (oasis.solve_part_1, oasis.solve_part_2), } diff --git a/advent_of_code/oasis.py b/advent_of_code/oasis.py new file mode 100644 index 0000000..b529987 --- /dev/null +++ b/advent_of_code/oasis.py @@ -0,0 +1,28 @@ +"Day 9: Mirage Maintenance" + +Sequence = tuple[int, ...] + + +def parse_sequence(desc: str) -> Sequence: + return tuple(int(num) for num in desc.split(" ")) + + +def extrapolate_sequence(sequence: tuple[int, ...]) -> int: + if any(sequence): + difference_sequence = tuple( + right - left for left, right in zip(sequence, sequence[1:]) + ) + next_difference = extrapolate_sequence(difference_sequence) + return sequence[-1] + next_difference + return 0 + + +def solve_part_1(input: str) -> int: + sequences = (parse_sequence(desc) for desc in input.split("\n")) + return sum(extrapolate_sequence(sequence) for sequence in sequences) + + +def solve_part_2(input: str) -> int: + sequences = (parse_sequence(desc) for desc in input.split("\n")) + reversed_sequences = (tuple(reversed(sequence)) for sequence in sequences) + return sum(extrapolate_sequence(sequence) for sequence in reversed_sequences) diff --git a/tests/oasis_test.py b/tests/oasis_test.py new file mode 100644 index 0000000..03b169a --- /dev/null +++ b/tests/oasis_test.py @@ -0,0 +1,46 @@ +from advent_of_code.oasis import ( + extrapolate_sequence, + parse_sequence, + solve_part_1, + solve_part_2, +) + + +def test_parse_sequencce(): + assert parse_sequence("1 2 3") == (1, 2, 3) + + +def test_extrapolate_sequence(): + assert extrapolate_sequence((0, 3, 6, 9, 12, 15)) == 18 + assert extrapolate_sequence((1, 3, 6, 10, 15, 21)) == 28 + assert extrapolate_sequence((10, 13, 16, 21, 30, 45)) == 68 + + +def test_solve_part_1(): + assert ( + solve_part_1( + "\n".join( + [ + "0 3 6 9 12 15", + "1 3 6 10 15 21", + "10 13 16 21 30 45", + ] + ) + ) + == 114 + ) + + +def test_solve_part_2(): + assert ( + solve_part_2( + "\n".join( + [ + "0 3 6 9 12 15", + "1 3 6 10 15 21", + "10 13 16 21 30 45", + ] + ) + ) + == 2 + )