2019: d10: ex1: add solution
This commit is contained in:
parent
72a07f9ac4
commit
cf42aaa2b0
81
2019/d10/ex1/ex1.py
Executable file
81
2019/d10/ex1/ex1.py
Executable file
|
@ -0,0 +1,81 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from itertools import chain
|
||||
from math import gcd
|
||||
from typing import Set, Tuple
|
||||
|
||||
Position = Tuple[int, int]
|
||||
|
||||
|
||||
def main() -> None:
|
||||
asteroids = [[c == "#" for c in line.rstrip()] for line in sys.stdin.readlines()]
|
||||
|
||||
def count_spotted(i: int, j: int) -> int:
|
||||
def is_valid(pos: Position) -> bool:
|
||||
return 0 <= pos[0] < len(asteroids) and 0 <= pos[1] < len(asteroids[0])
|
||||
|
||||
def pos_around(radius: int) -> Set[Position]:
|
||||
return set(
|
||||
chain(
|
||||
filter(
|
||||
is_valid,
|
||||
(
|
||||
(i - offset, j - radius)
|
||||
for offset in range(-radius, radius + 1)
|
||||
),
|
||||
),
|
||||
filter(
|
||||
is_valid,
|
||||
(
|
||||
(i - offset, j + radius)
|
||||
for offset in range(-radius, radius + 1)
|
||||
),
|
||||
),
|
||||
filter(
|
||||
is_valid,
|
||||
(
|
||||
(i - radius, j - offset)
|
||||
for offset in range(-radius, radius + 1)
|
||||
),
|
||||
),
|
||||
filter(
|
||||
is_valid,
|
||||
(
|
||||
(i + radius, j - offset)
|
||||
for offset in range(-radius, radius + 1)
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
seen: Set[Position] = set()
|
||||
ans = 0
|
||||
radius = 1
|
||||
while asteroids[i][j]: # Only do this if are on an asteroid
|
||||
to_visit = pos_around(radius)
|
||||
radius += 1
|
||||
if len(to_visit) == 0:
|
||||
break
|
||||
for pos in to_visit:
|
||||
if not asteroids[pos[0]][pos[1]]:
|
||||
continue # No asteroid there
|
||||
rel = (pos[0] - i, pos[1] - j)
|
||||
common = gcd(*rel)
|
||||
rel = (rel[0] // common, rel[1] // common)
|
||||
if rel in seen:
|
||||
continue # Already have an asteroid on this path
|
||||
seen.add(rel)
|
||||
ans += 1
|
||||
return ans
|
||||
|
||||
ans, y, x = max(
|
||||
(count_spotted(i, j), i, j)
|
||||
for i in range(len(asteroids))
|
||||
for j in range(len(asteroids[0]))
|
||||
)
|
||||
print(f"({x}, {y}): {ans}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Reference in a new issue