summaryrefslogtreecommitdiffstats
path: root/day15/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'day15/__init__.py')
-rw-r--r--day15/__init__.py42
1 files changed, 36 insertions, 6 deletions
diff --git a/day15/__init__.py b/day15/__init__.py
index 38bef35..7b580d9 100644
--- a/day15/__init__.py
+++ b/day15/__init__.py
@@ -2,8 +2,8 @@
2import re 2import re
3from abc import ABC 3from abc import ABC
4from dataclasses import dataclass, field 4from dataclasses import dataclass, field
5from typing import Union
6from typing import Tuple, Iterator, Set, List 5from typing import Tuple, Iterator, Set, List
6from typing import Union
7 7
8from aoc import BaseAssignment 8from aoc import BaseAssignment
9from aoc.datastructures import Coordinate 9from aoc.datastructures import Coordinate
@@ -25,7 +25,9 @@ class Sensor:
25 distance = self.coordinate.manhattan_distance(coordinate) 25 distance = self.coordinate.manhattan_distance(coordinate)
26 return distance <= self.radius 26 return distance <= self.radius
27 27
28 def x_coordinates_within_radius_at(self, y: int, map: "Map") -> Union[range, list]: 28 def x_coordinates_within_radius_at(
29 self, y: int, min_x: int = None, max_x: int = None
30 ) -> Union[range, list]:
29 31
30 coordinate = Coordinate(self.coordinate.x, y) 32 coordinate = Coordinate(self.coordinate.x, y)
31 33
@@ -35,11 +37,25 @@ class Sensor:
35 dy = abs(self.coordinate.y - y) 37 dy = abs(self.coordinate.y - y)
36 left_over = self.radius - dy 38 left_over = self.radius - dy
37 39
40 left_x = self.coordinate.x - left_over
41 right_x = self.coordinate.x + left_over
42
38 return range( 43 return range(
39 max(self.coordinate.x - left_over, map.width[0]), 44 max(left_x, min_x if min_x is not None else left_x - 1),
40 min(self.coordinate.x + left_over + 1, map.width[-1]), 45 min(right_x, max_x if max_x is not None else right_x + 1) + 1,
41 ) 46 )
42 47
48 def area_inside(self) -> Set[Coordinate]:
49 coordinates = set()
50
51 for y in range(
52 self.coordinate.y - (self.radius - 1), self.coordinate.y + self.radius
53 ):
54 for x in self.x_coordinates_within_radius_at(y):
55 coordinates.add(Coordinate(x, y))
56
57 return coordinates
58
43 59
44@dataclass 60@dataclass
45class Map: 61class Map:
@@ -98,7 +114,7 @@ class AssignmentOne(Assignment):
98 x_coordinates = { 114 x_coordinates = {
99 x 115 x
100 for sensor in map.sensors 116 for sensor in map.sensors
101 for x in sensor.x_coordinates_within_radius_at(y, map) 117 for x in sensor.x_coordinates_within_radius_at(y)
102 } 118 }
103 119
104 return len(x_coordinates) - len( 120 return len(x_coordinates) - len(
@@ -107,4 +123,18 @@ class AssignmentOne(Assignment):
107 123
108 124
109class AssignmentTwo(Assignment): 125class AssignmentTwo(Assignment):
110 pass 126 example_result = 56000011
127 example_kwargs = {"max": 20}
128
129 def run(self, input: Iterator[Tuple[Sensor, Coordinate]], max=4000000):
130 map = self.create_map(input)
131 coordinates = {Coordinate(x, y) for x in range(max) for y in range(max)}
132
133 print("Coordinates generated")
134
135 for sensor in map.sensors:
136 coordinates -= sensor.area_inside()
137
138 distress_beacon = (coordinates - map.beacons).pop()
139
140 return (distress_beacon.x * 4000000) + distress_beacon.y