summaryrefslogtreecommitdiffstats
path: root/day14
diff options
context:
space:
mode:
Diffstat (limited to 'day14')
-rw-r--r--day14/__init__.py133
-rw-r--r--day14/example.txt2
-rw-r--r--day14/input.txt112
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 -*-
2from abc import ABC
3from functools import lru_cache
4from typing import Tuple, Iterator, Set, Any, Optional
5
6from aoc import BaseAssignment
7
8Coordinate = Tuple[int, int]
9
10
11class 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
104class 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
114class 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 @@
1498,4 -> 498,6 -> 496,6
2503,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 @@
1481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54
2471,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
3465,117 -> 465,120 -> 464,120 -> 464,123 -> 476,123 -> 476,120 -> 471,120 -> 471,117
4451,104 -> 451,103 -> 451,104 -> 453,104 -> 453,97 -> 453,104 -> 455,104 -> 455,100 -> 455,104
5501,15 -> 506,15
6481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54
7471,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
8474,73 -> 474,74 -> 486,74 -> 486,73
9471,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
10481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54
11491,29 -> 495,29
12491,17 -> 496,17
13474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36
14454,107 -> 454,110 -> 450,110 -> 450,114 -> 467,114 -> 467,110 -> 459,110 -> 459,107
15462,84 -> 462,87 -> 455,87 -> 455,91 -> 469,91 -> 469,87 -> 466,87 -> 466,84
16462,84 -> 462,87 -> 455,87 -> 455,91 -> 469,91 -> 469,87 -> 466,87 -> 466,84
17471,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
18477,33 -> 482,33 -> 482,32
19485,29 -> 489,29
20481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54
21485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
22465,117 -> 465,120 -> 464,120 -> 464,123 -> 476,123 -> 476,120 -> 471,120 -> 471,117
23462,84 -> 462,87 -> 455,87 -> 455,91 -> 469,91 -> 469,87 -> 466,87 -> 466,84
24481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54
25474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36
26485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
27485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
28477,59 -> 477,60 -> 495,60
29471,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
30481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54
31465,117 -> 465,120 -> 464,120 -> 464,123 -> 476,123 -> 476,120 -> 471,120 -> 471,117
32465,117 -> 465,120 -> 464,120 -> 464,123 -> 476,123 -> 476,120 -> 471,120 -> 471,117
33465,117 -> 465,120 -> 464,120 -> 464,123 -> 476,123 -> 476,120 -> 471,120 -> 471,117
34451,104 -> 451,103 -> 451,104 -> 453,104 -> 453,97 -> 453,104 -> 455,104 -> 455,100 -> 455,104
35477,140 -> 488,140
36471,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
37485,23 -> 489,23
38471,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
39497,65 -> 502,65
40488,26 -> 492,26
41451,104 -> 451,103 -> 451,104 -> 453,104 -> 453,97 -> 453,104 -> 455,104 -> 455,100 -> 455,104
42479,29 -> 483,29
43474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36
44454,107 -> 454,110 -> 450,110 -> 450,114 -> 467,114 -> 467,110 -> 459,110 -> 459,107
45485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
46454,107 -> 454,110 -> 450,110 -> 450,114 -> 467,114 -> 467,110 -> 459,110 -> 459,107
47474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36
48471,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
49498,17 -> 503,17
50485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
51474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36
52485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
53488,20 -> 492,20
54494,67 -> 499,67
55471,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
56462,84 -> 462,87 -> 455,87 -> 455,91 -> 469,91 -> 469,87 -> 466,87 -> 466,84
57471,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
58454,107 -> 454,110 -> 450,110 -> 450,114 -> 467,114 -> 467,110 -> 459,110 -> 459,107
59485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
60505,17 -> 510,17
61487,67 -> 492,67
62451,104 -> 451,103 -> 451,104 -> 453,104 -> 453,97 -> 453,104 -> 455,104 -> 455,100 -> 455,104
63471,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
64474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36
65490,65 -> 495,65
66485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
67471,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
68478,81 -> 483,81
69501,67 -> 506,67
70484,69 -> 489,69
71471,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
72471,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
73454,107 -> 454,110 -> 450,110 -> 450,114 -> 467,114 -> 467,110 -> 459,110 -> 459,107
74462,84 -> 462,87 -> 455,87 -> 455,91 -> 469,91 -> 469,87 -> 466,87 -> 466,84
75485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
76497,29 -> 501,29
77493,63 -> 498,63
78471,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
79485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153