diff options
| -rw-r--r-- | day14/__init__.py | 133 | ||||
| -rw-r--r-- | day14/example.txt | 2 | ||||
| -rw-r--r-- | day14/input.txt | 112 |
3 files changed, 247 insertions, 0 deletions
diff --git a/day14/__init__.py b/day14/__init__.py new file mode 100644 index 0000000..44107de --- /dev/null +++ b/day14/__init__.py | |||
| @@ -0,0 +1,133 @@ | |||
| 1 | # -*- coding: utf-8 -*- | ||
| 2 | from abc import ABC | ||
| 3 | from functools import lru_cache | ||
| 4 | from typing import Tuple, Iterator, Set, Any, Optional | ||
| 5 | |||
| 6 | from aoc import BaseAssignment | ||
| 7 | |||
| 8 | Coordinate = Tuple[int, int] | ||
| 9 | |||
| 10 | |||
| 11 | class Assignment(BaseAssignment, ABC): | ||
| 12 | def __init__(self, path): | ||
| 13 | super().__init__(path) | ||
| 14 | |||
| 15 | self.cave_depth = None | ||
| 16 | |||
| 17 | def coordinate_ranges( | ||
| 18 | self, input: Iterator[str] | ||
| 19 | ) -> Iterator[Tuple[Coordinate, Coordinate]]: | ||
| 20 | for item in input: | ||
| 21 | last = None | ||
| 22 | |||
| 23 | for i in item.split(" -> "): | ||
| 24 | x, y = i.split(",") | ||
| 25 | |||
| 26 | coordinate = int(x), int(y) | ||
| 27 | |||
| 28 | if last is not None: | ||
| 29 | yield last, coordinate | ||
| 30 | |||
| 31 | last = coordinate | ||
| 32 | |||
| 33 | def coordinates(self, a: Coordinate, b: Coordinate) -> Iterator[Coordinate]: | ||
| 34 | for x in range(min(a[0], b[0]), max(a[0], b[0]) + 1): | ||
| 35 | for y in range(min(a[1], b[1]), max(a[1], b[1]) + 1): | ||
| 36 | yield x, y | ||
| 37 | |||
| 38 | def generate_rocks(self, input: Iterator[str]) -> Set[Coordinate]: | ||
| 39 | rocks = set( | ||
| 40 | coordinate | ||
| 41 | for coordinates in self.coordinate_ranges(input) | ||
| 42 | for coordinate in self.coordinates(*coordinates) | ||
| 43 | ) | ||
| 44 | |||
| 45 | self.cave_depth = self.get_cave_depth(rocks) | ||
| 46 | |||
| 47 | return rocks | ||
| 48 | |||
| 49 | def get_cave_depth(self, cave: Set[Coordinate]): | ||
| 50 | return max([item[1] for item in cave]) | ||
| 51 | |||
| 52 | def invalid_position(self, sand: Coordinate, cave: set[Coordinate]): | ||
| 53 | raise NotImplementedError() | ||
| 54 | |||
| 55 | def blocking(self, sand: Coordinate, cave: set[Coordinate]): | ||
| 56 | raise NotImplementedError() | ||
| 57 | |||
| 58 | def drop_sand( | ||
| 59 | self, sand: Coordinate, cave: Set[Coordinate] | ||
| 60 | ) -> Optional[Coordinate]: | ||
| 61 | if self.invalid_position(sand, cave): | ||
| 62 | return None | ||
| 63 | |||
| 64 | next_positions = [ | ||
| 65 | (sand[0], sand[1] + 1), | ||
| 66 | (sand[0] - 1, sand[1] + 1), | ||
| 67 | (sand[0] + 1, sand[1] + 1), | ||
| 68 | ] | ||
| 69 | |||
| 70 | non_blocking = [ | ||
| 71 | next_position | ||
| 72 | for next_position in next_positions | ||
| 73 | if not self.blocking(next_position, cave) | ||
| 74 | ] | ||
| 75 | |||
| 76 | if len(non_blocking) == 0: | ||
| 77 | return sand | ||
| 78 | |||
| 79 | return self.drop_sand(non_blocking[0], cave) | ||
| 80 | |||
| 81 | def generate_sand(self, cave: set[Coordinate]) -> Iterator[Coordinate]: | ||
| 82 | cave_copy = set(cave) | ||
| 83 | sand = (500, 0) | ||
| 84 | |||
| 85 | while True: | ||
| 86 | coordinate = self.drop_sand(sand, cave_copy) | ||
| 87 | |||
| 88 | if coordinate is None: | ||
| 89 | return | ||
| 90 | |||
| 91 | cave_copy.add(coordinate) | ||
| 92 | yield coordinate | ||
| 93 | |||
| 94 | def run(self, input: Iterator) -> Any: | ||
| 95 | cave = self.generate_rocks(input) | ||
| 96 | coordinates = set() | ||
| 97 | |||
| 98 | for sand in self.generate_sand(cave): | ||
| 99 | coordinates.add(sand) | ||
| 100 | |||
| 101 | return len(coordinates) | ||
| 102 | |||
| 103 | |||
| 104 | class AssignmentOne(Assignment): | ||
| 105 | example_result = 24 | ||
| 106 | |||
| 107 | def invalid_position(self, sand: Coordinate, cave: set[Coordinate]): | ||
| 108 | return sand[1] > self.cave_depth | ||
| 109 | |||
| 110 | def blocking(self, sand: Coordinate, cave: set[Coordinate]): | ||
| 111 | return sand in cave | ||
| 112 | |||
| 113 | |||
| 114 | class AssignmentTwo(Assignment): | ||
| 115 | example_result = 93 | ||
| 116 | |||
| 117 | def invalid_position(self, sand: Coordinate, cave: set[Coordinate]): | ||
| 118 | return False | ||
| 119 | |||
| 120 | def blocking(self, sand: Coordinate, cave: set[Coordinate]): | ||
| 121 | return sand in cave or sand[1] >= self.cave_depth + 2 | ||
| 122 | |||
| 123 | def run(self, input: Iterator) -> Any: | ||
| 124 | cave = self.generate_rocks(input) | ||
| 125 | coordinates = set() | ||
| 126 | |||
| 127 | for sand in self.generate_sand(cave): | ||
| 128 | coordinates.add(sand) | ||
| 129 | |||
| 130 | if sand == (500, 0): | ||
| 131 | break | ||
| 132 | |||
| 133 | return len(coordinates) | ||
diff --git a/day14/example.txt b/day14/example.txt new file mode 100644 index 0000000..4e87bb5 --- /dev/null +++ b/day14/example.txt | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | 498,4 -> 498,6 -> 496,6 | ||
| 2 | 503,4 -> 502,4 -> 502,9 -> 494,9 | ||
diff --git a/day14/input.txt b/day14/input.txt new file mode 100644 index 0000000..9ff2c57 --- /dev/null +++ b/day14/input.txt | |||
| @@ -0,0 +1,112 @@ | |||
| 1 | 481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54 | ||
| 2 | 471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136 | ||
| 3 | 465,117 -> 465,120 -> 464,120 -> 464,123 -> 476,123 -> 476,120 -> 471,120 -> 471,117 | ||
| 4 | 451,104 -> 451,103 -> 451,104 -> 453,104 -> 453,97 -> 453,104 -> 455,104 -> 455,100 -> 455,104 | ||
| 5 | 501,15 -> 506,15 | ||
| 6 | 481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54 | ||
| 7 | 471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136 | ||
| 8 | 474,73 -> 474,74 -> 486,74 -> 486,73 | ||
| 9 | 471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136 | ||
| 10 | 481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54 | ||
| 11 | 491,29 -> 495,29 | ||
| 12 | 491,17 -> 496,17 | ||
| 13 | 474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36 | ||
| 14 | 454,107 -> 454,110 -> 450,110 -> 450,114 -> 467,114 -> 467,110 -> 459,110 -> 459,107 | ||
| 15 | 462,84 -> 462,87 -> 455,87 -> 455,91 -> 469,91 -> 469,87 -> 466,87 -> 466,84 | ||
| 16 | 462,84 -> 462,87 -> 455,87 -> 455,91 -> 469,91 -> 469,87 -> 466,87 -> 466,84 | ||
| 17 | 471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136 | ||
| 18 | 477,33 -> 482,33 -> 482,32 | ||
| 19 | 485,29 -> 489,29 | ||
| 20 | 481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54 | ||
| 21 | 485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153 | ||
| 22 | 465,117 -> 465,120 -> 464,120 -> 464,123 -> 476,123 -> 476,120 -> 471,120 -> 471,117 | ||
| 23 | 462,84 -> 462,87 -> 455,87 -> 455,91 -> 469,91 -> 469,87 -> 466,87 -> 466,84 | ||
| 24 | 481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54 | ||
| 25 | 474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36 | ||
| 26 | 485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153 | ||
| 27 | 485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153 | ||
| 28 | 477,59 -> 477,60 -> 495,60 | ||
| 29 | 471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136 | ||
| 30 | 481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54 | ||
| 31 | 465,117 -> 465,120 -> 464,120 -> 464,123 -> 476,123 -> 476,120 -> 471,120 -> 471,117 | ||
| 32 | 465,117 -> 465,120 -> 464,120 -> 464,123 -> 476,123 -> 476,120 -> 471,120 -> 471,117 | ||
| 33 | 465,117 -> 465,120 -> 464,120 -> 464,123 -> 476,123 -> 476,120 -> 471,120 -> 471,117 | ||
| 34 | 451,104 -> 451,103 -> 451,104 -> 453,104 -> 453,97 -> 453,104 -> 455,104 -> 455,100 -> 455,104 | ||
| 35 | 477,140 -> 488,140 | ||
| 36 | 471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136 | ||
| 37 | 485,23 -> 489,23 | ||
| 38 | 471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136 | ||
| 39 | 497,65 -> 502,65 | ||
| 40 | 488,26 -> 492,26 | ||
| 41 | 451,104 -> 451,103 -> 451,104 -> 453,104 -> 453,97 -> 453,104 -> 455,104 -> 455,100 -> 455,104 | ||
| 42 | 479,29 -> 483,29 | ||
| 43 | 474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36 | ||
| 44 | 454,107 -> 454,110 -> 450,110 -> 450,114 -> 467,114 -> 467,110 -> 459,110 -> 459,107 | ||
| 45 | 485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153 | ||
| 46 | 454,107 -> 454,110 -> 450,110 -> 450,114 -> 467,114 -> 467,110 -> 459,110 -> 459,107 | ||
| 47 | 474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36 | ||
| 48 | 471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136 | ||
| 49 | 498,17 -> 503,17 | ||
| 50 | 485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153 | ||
| 51 | 474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36 | ||
| 52 | 485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153 | ||
| 53 | 488,20 -> 492,20 | ||
| 54 | 494,67 -> 499,67 | ||
| 55 | 471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136 | ||
| 56 | 462,84 -> 462,87 -> 455,87 -> 455,91 -> 469,91 -> 469,87 -> 466,87 -> 466,84 | ||
| 57 | 471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136 | ||
| 58 | 454,107 -> 454,110 -> 450,110 -> 450,114 -> 467,114 -> 467,110 -> 459,110 -> 459,107 | ||
| 59 | 485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153 | ||
| 60 | 505,17 -> 510,17 | ||
| 61 | 487,67 -> 492,67 | ||
| 62 | 451,104 -> 451,103 -> 451,104 -> 453,104 -> 453,97 -> 453,104 -> 455,104 -> 455,100 -> 455,104 | ||
| 63 | 471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136 | ||
| 64 | 474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36 | ||
| 65 | 490,65 -> 495,65 | ||
| 66 | 485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153 | ||
| 67 | 471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136 | ||
| 68 | 478,81 -> 483,81 | ||
| 69 | 501,67 -> 506,67 | ||
| 70 | 484,69 -> 489,69 | ||
| 71 | 471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136 | ||
| 72 | 471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136 | ||
| 73 | 454,107 -> 454,110 -> 450,110 -> 450,114 -> 467,114 -> 467,110 -> 459,110 -> 459,107 | ||
| 74 | 462,84 -> 462,87 -> 455,87 -> 455,91 -> 469,91 -> 469,87 -> 466,87 -> 466,84 | ||
| 75 | 485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153 | ||
| 76 | 497,29 -> 501,29 | ||
| 77 | 493,63 -> 498,63 | ||
| 78 | 471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136 | ||
| 79 | 485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153 | ||
| 80 | 494,26 -> 498,26 | ||
