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()
|