Skip to content

Commit 453322c

Browse files
author
Joth
committed
solve day 10
1 parent 6e74bdd commit 453322c

File tree

4 files changed

+269
-2
lines changed

4 files changed

+269
-2
lines changed

2019/Day 10/Part 1/AoC_2019_D10_P1.py

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,94 @@
33

44
from os import path
55

6+
class Location:
7+
def __init__(self, x, y):
8+
self.x = x
9+
self.y = y
10+
11+
def __repr__(self):
12+
return f'({self.x}, {self.y})'
13+
14+
15+
class Asteroid:
16+
def __init__(self, location):
17+
self.location = location
18+
self.detectable_asteroid_count = 0
19+
20+
def is_between(self, asteroid1, asteroid2):
21+
x, y = self.location.x, self.location.y
22+
x1, y1 = asteroid1.location.x, asteroid1.location.y
23+
x2, y2 = asteroid2.location.x, asteroid2.location.y
24+
25+
min_x, max_x = min(x1, x2), max(x1, x2)
26+
min_y, max_y = min(y1, y2), max(y1, y2)
27+
28+
if min_x <= x <= max_x and min_y <= y <= max_y:
29+
return y - y1 == ((y2 - y1)/(x2 - x1))*(x - x1) if x1 != x2 else x1 == x
30+
31+
return False
32+
33+
34+
class SpaceMap:
35+
36+
class Symbols:
37+
EMPTY = '.'
38+
ASTEROID = '#'
39+
40+
def __init__(self, raw_map):
41+
self._map = list(list(line) for line in raw_map.splitlines())
42+
self._HEIGHT = len(self._map)
43+
self._WIDTH = len(self._map[0])
44+
self._asteroids = []
45+
self._detect_asteroids()
46+
self._evaluate_every_asteroid()
47+
48+
def _detect_asteroids(self):
49+
for y in range(self._HEIGHT):
50+
for x in range(self._WIDTH):
51+
location = Location(x, y)
52+
if self._get(location) == SpaceMap.Symbols.ASTEROID:
53+
asteroid = Asteroid(location)
54+
self._set(location, asteroid)
55+
self._asteroids.append(asteroid)
56+
else:
57+
self._set(location, None)
58+
59+
def get_best_evaluated_asteroid(self):
60+
return max(self._asteroids, key=lambda x: x.detectable_asteroid_count)
61+
62+
def _evaluate_every_asteroid(self):
63+
for asteroid in self._asteroids:
64+
self._determinate_detectable_asteroids_for(asteroid)
65+
66+
def _determinate_detectable_asteroids_for(self, asteroid):
67+
asteroid.detectable_asteroid_count = 0
68+
for possible_detectable_asteroid in [x for x in self._asteroids if x != asteroid]:
69+
for possible_blocking_asteroid in [x for x in self._asteroids if x != possible_detectable_asteroid and x != asteroid]:
70+
if possible_blocking_asteroid.is_between(asteroid, possible_detectable_asteroid):
71+
break
72+
else:
73+
asteroid.detectable_asteroid_count += 1
74+
75+
def _is_asteroid(self, location):
76+
return isinstance(self._get(location), Asteroid)
77+
78+
def _is_empty(self, location):
79+
return self._get(location) is None
80+
81+
def _get(self, location):
82+
return self._map[location.y][location.x]
83+
84+
def _set(self, location, value):
85+
self._map[location.y][location.x] = value
86+
687

788
def main():
889
text_input = get_raw_input()
9-
pass
90+
space_map = SpaceMap(text_input)
91+
best_asteroid = space_map.get_best_evaluated_asteroid()
92+
print('Best asteroid:', best_asteroid.location)
93+
print('Detectable asteroid count:', best_asteroid.detectable_asteroid_count)
1094

1195

1296
def get_raw_input():

2019/Day 10/Part 1/input.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.#..#..###
2+
####.###.#
3+
....###.#.
4+
..###.##.#
5+
##.##.#.#.
6+
....###..#
7+
..#.#..#.#
8+
#..#.#.###
9+
.##...##.#
10+
.....#.#..

2019/Day 10/Part 2/AoC_2019_D10_P2.py

Lines changed: 126 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,136 @@
22
# Author: Joth (https://github.com/joth00)
33

44
from os import path
5+
import math
6+
7+
8+
class Location:
9+
def __init__(self, x, y):
10+
self.x = x
11+
self.y = y
12+
13+
def __repr__(self):
14+
return f'({self.x}, {self.y})'
15+
16+
17+
class Asteroid:
18+
def __init__(self, location):
19+
self.location = location
20+
self.detectable_asteroids = []
21+
22+
def is_between(self, asteroid1, asteroid2):
23+
x, y = self.location.x, self.location.y
24+
x1, y1 = asteroid1.location.x, asteroid1.location.y
25+
x2, y2 = asteroid2.location.x, asteroid2.location.y
26+
27+
min_x, max_x = min(x1, x2), max(x1, x2)
28+
min_y, max_y = min(y1, y2), max(y1, y2)
29+
30+
if min_x <= x <= max_x and min_y <= y <= max_y:
31+
return y - y1 == ((y2 - y1)/(x2 - x1))*(x - x1) if x1 != x2 else x1 == x
32+
33+
return False
34+
35+
def get_positive_angle_from(self, location):
36+
angle = math.atan2(self.location.y - location.y, self.location.x - location.x)
37+
return (angle + math.pi/2 + 2*math.pi) % (2*math.pi)
38+
39+
def __repr__(self):
40+
return repr(self.location)
41+
42+
43+
class MonitoringStation(Asteroid):
44+
def __init__(self, location):
45+
super().__init__(location)
46+
47+
@staticmethod
48+
def from_asteroid(asteroid):
49+
monitoring_station = MonitoringStation(asteroid.location)
50+
monitoring_station.detectable_asteroids = asteroid.detectable_asteroids
51+
return monitoring_station
52+
53+
def get_nth_vaporized_asteroid_in_map(self, n, space_map):
54+
last_vaporized_asteroids = self.detectable_asteroids[:]
55+
vaporized_asteroids_count = 0
56+
while vaporized_asteroids_count < n:
57+
space_map.determinate_detectable_asteroids_for(self)
58+
last_vaporized_asteroids = self.detectable_asteroids[:]
59+
space_map.vaporize_asteroids(last_vaporized_asteroids)
60+
vaporized_asteroids_count += len(last_vaporized_asteroids)
61+
62+
last_vaporized_asteroids.sort(key=lambda x: x.get_positive_angle_from(self.location), reverse=True)
63+
return last_vaporized_asteroids[vaporized_asteroids_count - n - 1]
64+
65+
66+
class SpaceMap:
67+
68+
class Symbols:
69+
EMPTY = '.'
70+
ASTEROID = '#'
71+
72+
def __init__(self, raw_map):
73+
self._map = list(list(line) for line in raw_map.splitlines())
74+
self._HEIGHT = len(self._map)
75+
self._WIDTH = len(self._map[0])
76+
self._asteroids = []
77+
self._detect_asteroids()
78+
self._evaluate_every_asteroid()
79+
80+
def _detect_asteroids(self):
81+
for y in range(self._HEIGHT):
82+
for x in range(self._WIDTH):
83+
location = Location(x, y)
84+
if self._get(location) == SpaceMap.Symbols.ASTEROID:
85+
asteroid = Asteroid(location)
86+
self._set(location, asteroid)
87+
self._asteroids.append(asteroid)
88+
else:
89+
self._set(location, None)
90+
91+
def _evaluate_every_asteroid(self):
92+
for asteroid in self._asteroids:
93+
self.determinate_detectable_asteroids_for(asteroid)
94+
95+
def get_best_evaluated_asteroid(self):
96+
return max(self._asteroids, key=lambda x: len(x.detectable_asteroids))
97+
98+
def determinate_detectable_asteroids_for(self, asteroid):
99+
asteroid.detectable_asteroid_count = 0
100+
asteroid.detectable_asteroids = []
101+
for possible_detectable_asteroid in [x for x in self._asteroids if x != asteroid]:
102+
for possible_blocking_asteroid in [x for x in self._asteroids if x != possible_detectable_asteroid and x != asteroid]:
103+
if possible_blocking_asteroid.is_between(asteroid, possible_detectable_asteroid):
104+
break
105+
else:
106+
asteroid.detectable_asteroids.append(possible_detectable_asteroid)
107+
108+
def vaporize_asteroids(self, asteroids):
109+
for asteroid in asteroids:
110+
self._set(asteroid.location, None)
111+
self._asteroids.remove(asteroid)
112+
113+
def _is_asteroid(self, location):
114+
return isinstance(self._get(location), Asteroid)
115+
116+
def _is_empty(self, location):
117+
return self._get(location) is None
118+
119+
def _get(self, location):
120+
return self._map[location.y][location.x]
121+
122+
def _set(self, location, value):
123+
self._map[location.y][location.x] = value
5124

6125

7126
def main():
8127
text_input = get_raw_input()
9-
pass
128+
space_map = SpaceMap(text_input)
129+
monitoring_station = MonitoringStation.from_asteroid(space_map.get_best_evaluated_asteroid())
130+
131+
location_of_200th_vaporized = monitoring_station.get_nth_vaporized_asteroid_in_map(200, space_map).location
132+
133+
print('Location of the 200th vaporized asteroid:', location_of_200th_vaporized)
134+
print('Result:', location_of_200th_vaporized.x*100 + location_of_200th_vaporized.y)
10135

11136

12137
def get_raw_input():

2019/Day 10/Part 2/input.txt

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#.#................#..............#......#......
2+
.......##..#..#....#.#.....##...#.........#.#...
3+
.#...............#....#.##......................
4+
......#..####.........#....#.......#..#.....#...
5+
.....#............#......#................#.#...
6+
....##...#.#.#.#.............#..#.#.......#.....
7+
..#.#.........#....#..#.#.........####..........
8+
....#...#.#...####..#..#..#.....#...............
9+
.............#......#..........#...........#....
10+
......#.#.........#...............#.............
11+
..#......#..#.....##...##.....#....#.#......#...
12+
...#.......##.........#.#..#......#........#.#..
13+
#.............#..........#....#.#.....#.........
14+
#......#.#................#.......#..#.#........
15+
#..#.#.....#.....###..#.................#..#....
16+
...............................#..........#.....
17+
###.#.....#.....#.............#.......#....#....
18+
.#.....#.........#.....#....#...................
19+
........#....................#..#...............
20+
.....#...#.##......#............#......#.....#..
21+
..#..#..............#..#..#.##........#.........
22+
..#.#...#.......#....##...#........#...#.#....#.
23+
.....#.#..####...........#.##....#....#......#..
24+
.....#..#..##...............................#...
25+
.#....#..#......#.#............#........##...#..
26+
.......#.....................#..#....#.....#....
27+
#......#..###...........#.#....#......#.........
28+
..............#..#.#...#.......#..#.#...#......#
29+
.......#...........#.....#...#.............#.#..
30+
..##..##.............#........#........#........
31+
......#.............##..#.........#...#.#.#.....
32+
#........#.........#...#.....#................#.
33+
...#.#...........#.....#.........#......##......
34+
..#..#...........#..........#...................
35+
.........#..#.......................#.#.........
36+
......#.#.#.....#...........#...............#...
37+
......#.##...........#....#............#........
38+
#...........##.#.#........##...........##.......
39+
......#....#..#.......#.....#.#.......#.##......
40+
.#....#......#..............#.......#...........
41+
......##.#..........#..................#........
42+
......##.##...#..#........#............#........
43+
..#.....#.................###...#.....###.#..#..
44+
....##...............#....#..................#..
45+
.....#................#.#.#.......#..........#..
46+
#........................#.##..........#....##..
47+
.#.........#.#.#...#...#....#........#..#.......
48+
...#..#.#......................#...............#

0 commit comments

Comments
 (0)