diff options
Diffstat (limited to 'day3/__init__.py')
| -rw-r--r-- | day3/__init__.py | 42 |
1 files changed, 25 insertions, 17 deletions
diff --git a/day3/__init__.py b/day3/__init__.py index ebe243e..aca90da 100644 --- a/day3/__init__.py +++ b/day3/__init__.py | |||
| @@ -8,7 +8,9 @@ from aoc.datastructures import Coordinate | |||
| 8 | 8 | ||
| 9 | 9 | ||
| 10 | class Assignment(BaseAssignment, ABC): | 10 | class Assignment(BaseAssignment, ABC): |
| 11 | def symbol_overlap(self, number_coordinates: list[Coordinate], symbols: set[Coordinate]) -> set[Coordinate]: | 11 | def symbol_overlap( |
| 12 | self, number_coordinates: list[Coordinate], symbols: set[Coordinate] | ||
| 13 | ) -> set[Coordinate]: | ||
| 12 | neighbours = { | 14 | neighbours = { |
| 13 | neighbour | 15 | neighbour |
| 14 | for coordinate in number_coordinates | 16 | for coordinate in number_coordinates |
| @@ -17,7 +19,9 @@ class Assignment(BaseAssignment, ABC): | |||
| 17 | 19 | ||
| 18 | return neighbours & symbols | 20 | return neighbours & symbols |
| 19 | 21 | ||
| 20 | def read_input(self, example=False) -> tuple[list[str], list[tuple[list[Coordinate], int]], set[Coordinate]]: | 22 | def read_input( |
| 23 | self, example=False | ||
| 24 | ) -> tuple[list[str], list[tuple[list[Coordinate], int]], set[Coordinate]]: | ||
| 21 | schematic = list(super().read_input(example)) | 25 | schematic = list(super().read_input(example)) |
| 22 | numbers: list[tuple[list[Coordinate], int]] = list() | 26 | numbers: list[tuple[list[Coordinate], int]] = list() |
| 23 | symbols: set[Coordinate] = set() | 27 | symbols: set[Coordinate] = set() |
| @@ -28,7 +32,7 @@ class Assignment(BaseAssignment, ABC): | |||
| 28 | for x, item in enumerate(row): | 32 | for x, item in enumerate(row): |
| 29 | if item.isdigit(): | 33 | if item.isdigit(): |
| 30 | if number is None: | 34 | if number is None: |
| 31 | number = [[], ''] | 35 | number = [[], ""] |
| 32 | 36 | ||
| 33 | number[0].append(Coordinate(x, y)) | 37 | number[0].append(Coordinate(x, y)) |
| 34 | number[1] += item | 38 | number[1] += item |
| @@ -38,7 +42,7 @@ class Assignment(BaseAssignment, ABC): | |||
| 38 | numbers.append((number[0], int(number[1]))) | 42 | numbers.append((number[0], int(number[1]))) |
| 39 | number = None | 43 | number = None |
| 40 | 44 | ||
| 41 | if item != '.': | 45 | if item != ".": |
| 42 | symbols.add(Coordinate(x, y)) | 46 | symbols.add(Coordinate(x, y)) |
| 43 | 47 | ||
| 44 | if number is not None: | 48 | if number is not None: |
| @@ -50,10 +54,14 @@ class Assignment(BaseAssignment, ABC): | |||
| 50 | class AssignmentOne(Assignment): | 54 | class AssignmentOne(Assignment): |
| 51 | example_result = 4361 | 55 | example_result = 4361 |
| 52 | 56 | ||
| 53 | def is_part_number(self, number_coordinates: list[Coordinate], symbols: set[Coordinate]) -> bool: | 57 | def is_part_number( |
| 58 | self, number_coordinates: list[Coordinate], symbols: set[Coordinate] | ||
| 59 | ) -> bool: | ||
| 54 | return len(self.symbol_overlap(number_coordinates, symbols)) > 0 | 60 | return len(self.symbol_overlap(number_coordinates, symbols)) > 0 |
| 55 | 61 | ||
| 56 | def run(self, input: tuple[list[tuple[list[Coordinate], int]], set[Coordinate]]) -> int: | 62 | def run( |
| 63 | self, input: tuple[list[tuple[list[Coordinate], int]], set[Coordinate]] | ||
| 64 | ) -> int: | ||
| 57 | _, numbers, symbols = input | 65 | _, numbers, symbols = input |
| 58 | 66 | ||
| 59 | part_numbers = [] | 67 | part_numbers = [] |
| @@ -68,14 +76,16 @@ class AssignmentOne(Assignment): | |||
| 68 | class AssignmentTwo(Assignment): | 76 | class AssignmentTwo(Assignment): |
| 69 | example_result = 467835 | 77 | example_result = 467835 |
| 70 | 78 | ||
| 71 | def run(self, input: tuple[list[tuple[list[Coordinate], int]], set[Coordinate]]) -> int: | 79 | def run( |
| 80 | self, input: tuple[list[tuple[list[Coordinate], int]], set[Coordinate]] | ||
| 81 | ) -> int: | ||
| 72 | schematic, numbers, symbols = input | 82 | schematic, numbers, symbols = input |
| 73 | 83 | ||
| 74 | possible_gears = {} | 84 | possible_gears = {} |
| 75 | 85 | ||
| 76 | for coordinates, number in numbers: | 86 | for coordinates, number in numbers: |
| 77 | for symbol in self.symbol_overlap(coordinates, symbols): | 87 | for symbol in self.symbol_overlap(coordinates, symbols): |
| 78 | if schematic[symbol.y][symbol.x] != '*': | 88 | if schematic[symbol.y][symbol.x] != "*": |
| 79 | continue | 89 | continue |
| 80 | 90 | ||
| 81 | if symbol not in possible_gears: | 91 | if symbol not in possible_gears: |
| @@ -83,12 +93,10 @@ class AssignmentTwo(Assignment): | |||
| 83 | 93 | ||
| 84 | possible_gears[symbol].append(number) | 94 | possible_gears[symbol].append(number) |
| 85 | 95 | ||
| 86 | return sum([ | 96 | return sum( |
| 87 | reduce( | 97 | [ |
| 88 | lambda total, number: total * number, | 98 | reduce(lambda total, number: total * number, numbers, 1) |
| 89 | numbers, | 99 | for symbol, numbers in possible_gears.items() |
| 90 | 1 | 100 | if len(numbers) > 1 |
| 91 | ) | 101 | ] |
| 92 | for symbol, numbers in possible_gears.items() | 102 | ) |
| 93 | if len(numbers) > 1 | ||
| 94 | ]) | ||
