diff --git a/aoc_2024/day_07/__init__.py b/aoc_2024/day_07/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/aoc_2024/day_07/a.py b/aoc_2024/day_07/a.py new file mode 100644 index 0000000..b9878fa --- /dev/null +++ b/aoc_2024/day_07/a.py @@ -0,0 +1,51 @@ +from dataclasses import dataclass +from typing import Generator +from aoc_2024.day_07.parser import Parser + + +@dataclass +class Day07PartASolver: + equations: list[tuple[int, list[int]]] + + @property + def solution(self) -> int: + output = 0 + for answer, nums in self.equations: + if self.can_be_true(answer, nums): + output += answer + return output + + def can_be_true(self, answer: int, nums: list[int]) -> bool: + return True in self.has_solution(answer, nums, nums[0], 1) + + def has_solution( + self, + answer: int, + nums: list[int], + so_far: int, + index: int, + ) -> Generator[bool, None, None]: + if so_far > answer: + yield False + elif index == len(nums): + yield so_far == answer + else: + yield from self.has_solution(answer, nums, so_far + nums[index], index + 1) + yield from self.has_solution(answer, nums, so_far * nums[index], index + 1) + + +def solve(input: str) -> int: + data = Parser.parse(input) + solver = Day07PartASolver(data) + + return solver.solution + + +def get_solution() -> int: + with open("aoc_2024/day_07/input.txt", "r") as f: + input = f.read() + return solve(input) + + +if __name__ == "__main__": + print(get_solution()) diff --git a/aoc_2024/day_07/b.py b/aoc_2024/day_07/b.py new file mode 100644 index 0000000..1ff5791 --- /dev/null +++ b/aoc_2024/day_07/b.py @@ -0,0 +1,54 @@ +from dataclasses import dataclass +from typing import Generator +from aoc_2024.day_07.parser import Parser + + +@dataclass +class Day07PartBSolver: + equations: list[tuple[int, list[int]]] + + @property + def solution(self) -> int: + output = 0 + for answer, nums in self.equations: + if self.can_be_true(answer, nums): + output += answer + return output + + def can_be_true(self, answer: int, nums: list[int]) -> bool: + return True in self.has_solution(answer, nums, nums[0], 1) + + def has_solution( + self, + answer: int, + nums: list[int], + so_far: int, + index: int, + ) -> Generator[bool, None, None]: + if so_far > answer: + yield False + elif index == len(nums): + yield so_far == answer + else: + yield from self.has_solution(answer, nums, so_far + nums[index], index + 1) + yield from self.has_solution(answer, nums, so_far * nums[index], index + 1) + yield from self.has_solution( + answer, nums, int(f"{so_far}{nums[index]}"), index + 1 + ) + + +def solve(input: str) -> int: + data = Parser.parse(input) + solver = Day07PartBSolver(data) + + return solver.solution + + +def get_solution() -> int: + with open("aoc_2024/day_07/input.txt", "r") as f: + input = f.read() + return solve(input) + + +if __name__ == "__main__": + print(get_solution()) diff --git a/aoc_2024/day_07/from_prompt.py b/aoc_2024/day_07/from_prompt.py new file mode 100644 index 0000000..be75432 Binary files /dev/null and b/aoc_2024/day_07/from_prompt.py differ diff --git a/aoc_2024/day_07/input.txt b/aoc_2024/day_07/input.txt new file mode 100644 index 0000000..fb20168 Binary files /dev/null and b/aoc_2024/day_07/input.txt differ diff --git a/aoc_2024/day_07/parser.py b/aoc_2024/day_07/parser.py new file mode 100644 index 0000000..39fd658 --- /dev/null +++ b/aoc_2024/day_07/parser.py @@ -0,0 +1,10 @@ +class Parser: + @staticmethod + def parse(input: str) -> list[tuple[int, list[int]]]: + lines = input.strip().splitlines() + return [Parser.parse_line(line) for line in lines] + + @staticmethod + def parse_line(line: str) -> tuple[int, list[int]]: + left, right = line.split(": ") + return int(left), [int(num) for num in right.split(" ")] diff --git a/tests/test_day_07/__init__.py b/tests/test_day_07/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_day_07/test_a.py b/tests/test_day_07/test_a.py new file mode 100644 index 0000000..eeec72b --- /dev/null +++ b/tests/test_day_07/test_a.py @@ -0,0 +1,10 @@ +from aoc_2024.day_07.a import get_solution, solve +from aoc_2024.day_07.from_prompt import SAMPLE_DATA, SAMPLE_SOLUTION_A, SOLUTION_A + + +def test_solve(): + assert solve(SAMPLE_DATA) == SAMPLE_SOLUTION_A + + +def test_my_solution(): + assert get_solution() == SOLUTION_A diff --git a/tests/test_day_07/test_b.py b/tests/test_day_07/test_b.py new file mode 100644 index 0000000..b140cbf --- /dev/null +++ b/tests/test_day_07/test_b.py @@ -0,0 +1,10 @@ +from aoc_2024.day_07.b import get_solution, solve +from aoc_2024.day_07.from_prompt import SAMPLE_DATA, SAMPLE_SOLUTION_B, SOLUTION_B + + +def test_solve(): + assert solve(SAMPLE_DATA) == SAMPLE_SOLUTION_B + + +def test_my_solution(): + assert get_solution() == SOLUTION_B