Day 10: much more efficient solution
This commit is contained in:
parent
0063b5e952
commit
39090d4e94
|
@ -1,46 +1,31 @@
|
||||||
import math
|
import math
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
with open("day10.txt", "rt") as input_file:
|
with open("day10.txt", "rt") as input_file:
|
||||||
amap = [line.rstrip() for line in input_file.readlines()]
|
amap = [line.rstrip() for line in input_file.readlines()]
|
||||||
|
|
||||||
ast_positions = []
|
asteroids = []
|
||||||
for x, line in enumerate(amap):
|
for y, line in enumerate(amap):
|
||||||
for y, value in enumerate(line):
|
for x, value in enumerate(line):
|
||||||
if value == "#":
|
if value == "#":
|
||||||
ast_positions.append((x, y))
|
asteroids.append((x, y))
|
||||||
|
|
||||||
best_vis = 0
|
best_vis = 0
|
||||||
for pos in ast_positions:
|
best_pos = None
|
||||||
best_vis = max(best_vis, num_visible_asts(ast_positions, pos))
|
for pos in asteroids:
|
||||||
|
vis = num_visible_asts(asteroids, pos)
|
||||||
print("Best visibility is", best_vis)
|
if vis > best_vis:
|
||||||
|
best_vis, best_pos = vis, pos
|
||||||
|
print(f"Best visibility is {best_vis} at {best_pos}.")
|
||||||
|
|
||||||
def num_visible_asts(asts, ref):
|
def num_visible_asts(asts, ref):
|
||||||
count = 0
|
asts = asts.copy()
|
||||||
for ast in asts:
|
asts.remove(ref)
|
||||||
if ast[0] == ref[0] and ast[1] == ref[1]:
|
angles = [np.angle(np.complex(ast[0] - ref[0], ast[1] - ref[1])) for ast in asts]
|
||||||
continue
|
return len(set(angles))
|
||||||
if is_visible(asts, ref, ast):
|
|
||||||
count += 1
|
|
||||||
return count
|
|
||||||
|
|
||||||
def is_visible(asts, ref, target):
|
|
||||||
for ast in asts:
|
|
||||||
if ast[0] == ref[0] and ast[1] == ref[1]:
|
|
||||||
continue
|
|
||||||
if ast[0] == target[0] and ast[1] == target[1]:
|
|
||||||
continue
|
|
||||||
if is_on_line(ref, target, ast):
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def is_on_line(a, b, p):
|
|
||||||
return math.isclose(dist(a, b), dist(a, p) + dist(b, p))
|
|
||||||
|
|
||||||
def dist(a, b):
|
|
||||||
return math.sqrt((a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
Loading…
Reference in a new issue