Day 10: much more efficient solution

This commit is contained in:
Dece 2019-12-15 18:42:31 +01:00
parent 0063b5e952
commit 39090d4e94

View file

@ -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__":