-
Notifications
You must be signed in to change notification settings - Fork 0
/
10.py
103 lines (75 loc) · 2.27 KB
/
10.py
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import math
import numpy as np
def getAngle(p1, p2):
dx = p2["x"] - p1["x"]
dy = p2["y"] - p1["y"]
h = math.sqrt(dx**2 + dy**2)
angle = math.asin(dx/h)
if dx >= 0 and dy > 0:
radians = math.asin(dx/h)
angle = math.degrees(radians)
elif dx > 0 and dy <= 0:
radians = math.acos(dx/h)
angle = math.degrees(radians) + 90
elif dx <= 0 and dy < 0:
radians = math.asin(abs(dx)/h)
angle = math.degrees(radians) + 180
elif dx <= 0 and dy >= 0:
radians = math.acos(abs(dx)/h)
angle = math.degrees(radians) + 270
return round(angle,2)
def getDistance(p1, p2):
dx = p2["x"] - p1["x"]
dy = p2["y"] - p1["y"]
h = math.sqrt(dx**2 + dy**2)
return h
if __name__ == "__main__":
with open("input/10.input", "r") as file:
asteroids = []
for y, line in enumerate(file):
for x, char in enumerate(line):
if char is "#":
asteroids.append({"x": x, "y": -y})
base_fitnesses = []
for base in asteroids:
detected_asteroids_count = 0
detected_asteroids_angles = []
for asteroid in asteroids:
if asteroid is not base:
angle = getAngle(base, asteroid)
if angle not in detected_asteroids_angles:
detected_asteroids_angles.append(angle)
detected_asteroids_count += 1
base_fitnesses.append({
"coords": base,
"asteroids": detected_asteroids_count
})
base_fitnesses.sort(key=lambda entry: entry["asteroids"], reverse=True)
ideal_base = base_fitnesses[0]
print("Part 1 | most asteroids spotted from a base:", ideal_base["asteroids"])
base = ideal_base["coords"]
asteroids_by_angle = {}
for asteroid in asteroids:
if asteroid is not base:
angle = getAngle(base, asteroid)
distance = getDistance(base, asteroid)
entry = {
"distance": distance,
"coords": asteroid
}
if angle in asteroids_by_angle.keys():
asteroids_by_angle[angle].append(entry)
else:
asteroids_by_angle[angle] = [entry]
vaporized = 0
while True:
for angle in sorted(asteroids_by_angle):
asteroids = asteroids_by_angle[angle]
if len(asteroids):
asteroids.sort(key=lambda asteroid: asteroid["distance"])
vaporized_asteroid = asteroids[0]
asteroids.remove(vaporized_asteroid)
vaporized += 1
if vaporized is 200:
print("Part 2 | 200th vaporized asteroid:", vaporized_asteroid["coords"])
break