|
|
|
|
@ -1,4 +1,4 @@ |
|
|
|
|
from math import atan2 |
|
|
|
|
from math import atan2, sqrt |
|
|
|
|
import os |
|
|
|
|
from typing import Tuple |
|
|
|
|
|
|
|
|
|
@ -6,20 +6,45 @@ from typing import Tuple |
|
|
|
|
inputfile = os.path.join(os.path.dirname(__file__), "input/day10_input") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_asteroids(): |
|
|
|
|
with open(inputfile) as fp: |
|
|
|
|
lines = [x.rstrip() for x in fp.readlines()] |
|
|
|
|
return [(x, y) |
|
|
|
|
for y, line in enumerate(lines) |
|
|
|
|
for x, m in enumerate(line) |
|
|
|
|
if m == '#'] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def calc_arc(origin: Tuple[int, int], target: Tuple[int, int]) -> float: |
|
|
|
|
return atan2(target[0] - origin[0], target[1] - origin[1]) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_day10a(): |
|
|
|
|
with open(inputfile) as fp: |
|
|
|
|
lines = [x.rstrip() for x in fp.readlines()] |
|
|
|
|
asts = [(x, y) |
|
|
|
|
for x, line in enumerate(lines) |
|
|
|
|
for y, m in enumerate(line) |
|
|
|
|
if m == '#'] |
|
|
|
|
|
|
|
|
|
max = 0 |
|
|
|
|
found = (0, 0) |
|
|
|
|
asts = get_asteroids() |
|
|
|
|
for my in asts: |
|
|
|
|
angles = {calc_arc(my, target) for target in asts} |
|
|
|
|
max = len(angles) if len(angles) > max else max |
|
|
|
|
if len(angles) > max: |
|
|
|
|
max = len(angles) |
|
|
|
|
found = my |
|
|
|
|
|
|
|
|
|
print(f'Station is at {found} with {max} visible asteroids') |
|
|
|
|
assert max == 303 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_day10b(): |
|
|
|
|
station = (26, 29) |
|
|
|
|
res = None |
|
|
|
|
count = 0 |
|
|
|
|
asts = get_asteroids() |
|
|
|
|
asts.remove(station) |
|
|
|
|
while not res: |
|
|
|
|
angles = {calc_arc(station, target): target for target in asts} |
|
|
|
|
for ang in sorted(angles.keys(), reverse=True): |
|
|
|
|
asts.remove(angles[ang]) |
|
|
|
|
count += 1 |
|
|
|
|
if count == 200: |
|
|
|
|
res = angles[ang] |
|
|
|
|
break |
|
|
|
|
assert res[0] * 100 + res[1] == 408 |
|
|
|
|
|