96 lines
2.2 KiB
Python
96 lines
2.2 KiB
Python
from collections import OrderedDict, defaultdict, deque
|
|
from math import atan2
|
|
|
|
from output import answer
|
|
|
|
n = 10
|
|
title = "Monitoring Station"
|
|
|
|
|
|
@answer(1, "The monitor station will see {} asteroids at best")
|
|
def part_1(o):
|
|
return o[0]
|
|
|
|
|
|
@answer(
|
|
2,
|
|
"The asteroid at y=3 x=17 (checksum {}) will be the 200th lazer vapored asteroid, making some elf happy",
|
|
)
|
|
def part_2(o):
|
|
return o[1]
|
|
|
|
|
|
def solve(data):
|
|
matrix = data.strip().split()
|
|
pos, visible = _map_visible_asteroids(matrix)
|
|
|
|
p1 = len(set(dict(visible).values()))
|
|
|
|
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
|
|
|
|
p2 = x * 100 + y
|
|
|
|
return p1, p2
|
|
|
|
|
|
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__":
|
|
with open("./input/10.txt", "r") as f:
|
|
inp = f.read().strip()
|
|
|
|
inp = solve(inp)
|
|
|
|
a = part_1(inp)
|
|
b = part_2(inp)
|
|
|
|
assert a == 292
|
|
assert b == 317
|