83 lines
2.1 KiB
Python
83 lines
2.1 KiB
Python
from collections import OrderedDict, defaultdict, deque
|
|
from math import atan2
|
|
from output import answer, puzzleinput
|
|
|
|
n = 10
|
|
title = "Monitoring Station"
|
|
|
|
|
|
@puzzleinput(n)
|
|
def parse_input(data):
|
|
return data.strip().split()
|
|
|
|
|
|
@answer(1, "The monitor station will see {} asteroids at best")
|
|
def part_1(matrix):
|
|
_pos, visible = _map_visible_asteroids(matrix)
|
|
return len(set(dict(visible).values()))
|
|
|
|
|
|
@answer(
|
|
2,
|
|
"The asteroid at y=3 x=17 (checksum {}) will be the 200th lazer vapored asteroid, making some elf happy",
|
|
)
|
|
def part_2(matrix):
|
|
pos, visible = _map_visible_asteroids(matrix)
|
|
targets_upper = defaultdict(list)
|
|
targets_lower = defaultdict(list)
|
|
targets = dict()
|
|
|
|
for xy, angle in visible:
|
|
if angle < 0:
|
|
targets_lower[angle].append(xy)
|
|
else:
|
|
targets_upper[angle].append(xy)
|
|
|
|
for k, v in OrderedDict(
|
|
sorted(targets_upper.items(), key=lambda x: x[0], reverse=True)
|
|
+ sorted(targets_lower.items(), key=lambda x: x[0], reverse=True)
|
|
).items():
|
|
targets[k] = deque(
|
|
sorted(
|
|
v,
|
|
key=lambda xy: sum(abs(pos[i] - xy[i]) for i in range(2)),
|
|
)
|
|
)
|
|
|
|
vapored = 0
|
|
x = 0
|
|
y = 0
|
|
while vapored < 200:
|
|
popped = False
|
|
for tk in targets.keys():
|
|
if targets[tk]:
|
|
x, y = targets[tk].pop()
|
|
vapored += 1
|
|
popped = True
|
|
if vapored == 200:
|
|
break
|
|
if not popped:
|
|
break
|
|
return x * 100 + y
|
|
|
|
|
|
def _map_visible_asteroids(matrix):
|
|
asteroids = []
|
|
visible = defaultdict(int)
|
|
|
|
for y in range(len(matrix)):
|
|
for x in range(len(matrix[0])):
|
|
if matrix[y][x] == "#":
|
|
asteroids.append((x, y))
|
|
for a, b in asteroids:
|
|
visible[(a, b)] = [
|
|
((x, y), atan2(x - a, y - b)) for x, y in asteroids if (a, b) != (x, y)
|
|
]
|
|
|
|
return max(visible.items(), key=lambda x: len(set(dict(x[1]).values())))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parsed = parse_input()
|
|
part_1(parsed)
|
|
part_2(parsed)
|