| @@ -0,0 +1,41 @@ | |||
| import itertools | |||
| import math | |||
| import sys | |||
| from functools import partial | |||
| def measure(start, other): | |||
| dx, dy = other[0] - start[0], other[1] - start[1] | |||
| angle = math.atan2(-dx, dy) | |||
| return -math.pi if angle == math.pi else angle, math.hypot(dx, dy), other | |||
| def seek(start, asteroids): | |||
| pending = sorted(measure(start, ast) for ast in asteroids) | |||
| while pending: | |||
| copy = pending.copy() | |||
| pending = [] | |||
| out = {} | |||
| for angle, dist, ast in copy: | |||
| if angle in out: | |||
| pending.append((angle, dist, ast)) | |||
| else: | |||
| out[angle] = ast | |||
| yield list(out.values()) | |||
| text = sys.stdin.read() | |||
| asteroids = { | |||
| (X, Y) | |||
| for Y, line in enumerate(text.splitlines()) | |||
| for X, cell in enumerate(line) | |||
| if cell == '#' | |||
| } | |||
| visibility = {ast: len(next(seek(ast, asteroids))) for ast in asteroids} | |||
| origin = max(visibility, key=visibility.get) | |||
| print(visibility[origin]) | |||
| ordering = list(itertools.chain(*seek(origin, asteroids))) | |||
| x, y = ordering[200 - 1] | |||
| print(100 * x + y) | |||