advent-of-code/2019/d10/ex1/ex1.py

52 lines
1.2 KiB
Python
Raw Permalink Normal View History

2019-12-11 02:04:28 +01:00
#!/usr/bin/env python
import sys
from math import gcd
2019-12-11 16:37:36 +01:00
from typing import NamedTuple, Set
2019-12-11 02:04:28 +01:00
2019-12-11 16:37:36 +01:00
class Position(NamedTuple):
x: int
y: int
2019-12-11 02:04:28 +01:00
2019-12-11 16:37:36 +01:00
def main() -> None:
asteroids = [
Position(x, y)
for y, line in enumerate(sys.stdin.readlines())
for x, c in enumerate(line.rstrip())
if c == "#"
]
def count_spotted(x: int, y: int) -> int:
2019-12-11 02:04:28 +01:00
seen: Set[Position] = set()
ans = 0
radius = 1
2019-12-11 16:37:36 +01:00
while True:
def is_r_away(pos: Position) -> bool:
return max(abs(pos.x - x), abs(pos.y - y)) == radius
to_visit = list(filter(is_r_away, asteroids))
2019-12-11 02:04:28 +01:00
radius += 1
if len(to_visit) == 0:
break
for pos in to_visit:
2019-12-11 16:37:36 +01:00
rel = (pos.x - x, pos.y - y)
2019-12-11 02:04:28 +01:00
common = gcd(*rel)
2019-12-11 16:37:36 +01:00
rel = Position(*(a // common for a in rel))
2019-12-11 02:04:28 +01:00
if rel in seen:
continue # Already have an asteroid on this path
seen.add(rel)
ans += 1
2019-12-11 16:37:36 +01:00
2019-12-11 02:04:28 +01:00
return ans
2019-12-11 16:37:36 +01:00
ans, x, y = max((count_spotted(*pos), *pos) for pos in asteroids)
2019-12-11 02:04:28 +01:00
print(f"({x}, {y}): {ans}")
if __name__ == "__main__":
main()