From e7be6481214620e361f00b2ac5ebbec8bb24ac28 Mon Sep 17 00:00:00 2001 From: Dece Date: Sun, 15 Dec 2019 23:34:38 +0100 Subject: [PATCH] Day 10 part 2 --- 2019/day10.py | 71 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 8 deletions(-) diff --git a/2019/day10.py b/2019/day10.py index fd80d96..480049b 100644 --- a/2019/day10.py +++ b/2019/day10.py @@ -1,14 +1,24 @@ -import math +from collections import defaultdict +import time import numpy as np DIM = 40 +EX = [ + ".#....#####...#..", + "##...##.#####..##", + "##...#...#.#####.", + "..#.....#...###..", + "..#.#.....#....##", +] + def main(): with open("day10.txt", "rt") as input_file: amap = [line.rstrip() for line in input_file.readlines()] + # amap = [line.rstrip() for line in EX] asteroids = [] for y, line in enumerate(amap): @@ -24,27 +34,72 @@ def main(): if vis > best_vis: best_vis, best_pos = vis, pos print(f"Best visibility is {best_vis} at {best_pos}.") - draw(asteroids, best_pos) -def draw(asteroids, station_pos): + # Part 2 + pos = best_pos + asteroids.remove(pos) + destroyed = 0 + angles = defaultdict(list) + for a in asteroids: + angle = np.angle(np.complex(a[0] - pos[0], a[1] - pos[1]), deg=True) + angles[angle].append(a) + current_angle = -90.0 + while asteroids: + print(f"Laser at {pos}.") + print(f"Current angle: {current_angle}.") + targets = angles[current_angle] + try: + next_angle = min([a for a in angles.keys() if a > current_angle]) + except ValueError: + next_angle = -180.0 + if not targets: + current_angle = next_angle + continue + print(f"Acquired targets {targets}.") + nearest_target = min(targets, key=lambda t: dist_idea(pos, t)) + print(f"Nearest target: {nearest_target}.") + + # Pew! + asteroids.remove(nearest_target) + targets.remove(nearest_target) + + destroyed += 1 + print(f"Destroyed {nearest_target} -- total of {destroyed} asteroids.") + if destroyed == 200: + print(f"Destroyed 200th asteroid at {nearest_target}.") + break + + current_angle = next_angle + + draw(asteroids, pos, [nearest_target]) + time.sleep(0.2) + + print(f"Answer: {100 * nearest_target[0] + nearest_target[1]}.") + +def draw(asteroids, station_pos, specials=[]): for y in range(DIM): print(str(y).zfill(2), end=" ") for x in range(DIM): if (x, y) == station_pos: print("@", end="") + elif (x, y) in specials: + print("X", end="") elif (x, y) in asteroids: print("█", end="") else: print(" ", end="") print() - print(" " + "0123456789"*4) + print(" " + "0123456789"*4) -def num_visible_asts(asts, ref): - asts = asts.copy() - asts.remove(ref) - angles = [np.angle(np.complex(ast[0] - ref[0], ast[1] - ref[1])) for ast in asts] +def num_visible_asts(asteroids, ref): + asteroids = asteroids.copy() + asteroids.remove(ref) + angles = [np.angle(np.complex(a[0] - ref[0], a[1] - ref[1])) for a in asteroids] return len(set(angles)) +def dist_idea(a, b): + return (a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2 + if __name__ == "__main__": main()