diff options
Diffstat (limited to 'solutions/py/d10.py')
| -rw-r--r-- | solutions/py/d10.py | 261 |
1 files changed, 0 insertions, 261 deletions
diff --git a/solutions/py/d10.py b/solutions/py/d10.py deleted file mode 100644 index 0d918d9..0000000 --- a/solutions/py/d10.py +++ /dev/null @@ -1,261 +0,0 @@ -import math -import os -import queue -import sys -import time - -def red(dcoord): - dx = dcoord[0] - dy = dcoord[1] - if dx == 0: - return (0, (1 if dy > 0 else -1)) - if dy == 0: - return ((1 if dx > 0 else -1), 0) - gcd = math.gcd(dx, dy) - return (dx // gcd, dy // gcd) - -def angle(x, y): # from y-axis, clockwise - if x >= 0 and y > 0: - return math.atan(abs(x/y)) - if x > 0 and y <= 0: - return math.atan(abs(y/x)) + math.pi/2 - if x <= 0 and y < 0: - return math.atan(abs(x/y)) + math.pi - else: - return math.atan(abs(y/x)) + 3*math.pi / 2 - -def pt1(input): - asteroids = set() - res = {} - - max_x = len(input[0].rstrip()) - max_y = len(input) - - for y in range(max_y): - for x in range(max_x): - if input[y][x] == "#": - asteroids.add((x,y)) - - for a in asteroids: - candidates = set(asteroids.copy()) - candidates.remove(a) - seen = set() - while len(candidates) > 0: - c = candidates.pop() - seen.add(c) - dx = c[0] - a[0] - dy = c[1] - a[1] - x = a[0] - y = a[1] - x += dx - y += dy - dx, dy = red((dx, dy)) - x += dx - y += dy - while x < max_x and y < max_y and x >= 0 and y >= 0: - if (x, y) in candidates: - candidates.remove((x, y)) - if (x, y) in seen: - seen.remove((x, y)) - x += dx - y += dy - res[a] = seen - - best = [0, 0, 0] - for coord in res: - amount = len(res[coord]) - if amount > best[0]: - best = [amount, coord, res[coord]] - return (best[1], best[0]) - -def pt2(input): - asteroids = set() - res = {} - - max_x = len(input[0].rstrip()) - max_y = len(input) - - for y in range(max_y): - for x in range(max_x): - if input[y][x] == "#": - asteroids.add((x,y)) - - for a in asteroids: - candidates = set(asteroids.copy()) - candidates.remove(a) - seen = set() - while len(candidates) > 0: - c = candidates.pop() - seen.add(c) - dx = c[0] - a[0] - dy = c[1] - a[1] - x = a[0] - y = a[1] - x += dx - y += dy - dx, dy = red((dx, dy)) - x += dx - y += dy - while x < max_x and y < max_y and x >= 0 and y >= 0: - if (x, y) in candidates: - candidates.remove((x, y)) - if (x, y) in seen: - seen.remove((x, y)) - x += dx - y += dy - res[a] = seen - - best = [0, 0, 0] - for coord in res: - amount = len(res[coord]) - if amount > best[0]: - best = [amount, coord, res[coord]] - asteroids.remove(best[1]) - x0 = best[1][0] - y0 = best[1][1] - - angles = {} - q = queue.Queue() - for a in asteroids: - angles[a] = angle(a[0] - x0, y0 - a[1]) - - for k, v in sorted(angles.items(), key=lambda item: item[1]): - if k in best[2]: - q.put(k) - - destroyed = 1 - while not q.empty(): - asteroid = q.get() - if destroyed == 200: - return (asteroid, asteroid[0]*100 + asteroid[1]) - asteroids.remove(asteroid) - destroyed += 1 - - # add next asteroid behind to queue - dx = asteroid[0] - x0 - dy = asteroid[1] - y0 - x = x0 - y = y0 - x += dx - y += dy - dx, dy = red((dx, dy)) - x += dx - y += dy - while x < max_x and y < max_y and x >= 0 and y >= 0: - if (x, y) in asteroids: - q.put((x, y)) - break - x += dx - y += dy - -def print_map(coords, w, h): - time.sleep(0.01) - os.system("clear") - s = "" - for y in range(w): - for x in range(h): - s += (coords[(x, y)] + " ") if (x,y) in coords else " " - s += "\n" - print(s) - -def visualize(input): - asteroids = set() - res = {} - - max_x = len(input[0].rstrip()) - max_y = len(input) - - for y in range(max_y): - for x in range(max_x): - if input[y][x] == "#": - asteroids.add((x,y)) - - #print_map(asteroids, max_x, max_y) - - for a in asteroids: - print(a) - time.sleep(3) - candidates = set(asteroids.copy()) - candidates.remove(a) - seen = set() - while len(candidates) > 0: - #print(len(candidates)) - time.sleep(0.02) - union = {a: "\u2588"} - for c in candidates: - union[c] = "C" - for s in seen: - union[s] = "s" - print_map(union, max_x, max_y) - c = candidates.pop() - seen.add(c) - dx = c[0] - a[0] - dy = c[1] - a[1] - x = a[0] - y = a[1] - x += dx - y += dy - dx, dy = red((dx, dy)) - x += dx - y += dy - while x < max_x and y < max_y and x >= 0 and y >= 0: - if (x, y) in candidates: - candidates.remove((x, y)) - if (x, y) in seen: - seen.remove((x, y)) - x += dx - y += dy - res[a] = seen - - best = [0, 0, 0] - for coord in res: - amount = len(res[coord]) - if amount > best[0]: - best = [amount, coord, res[coord]] - asteroids.remove(best[1]) - x0 = best[1][0] - y0 = best[1][1] - - angles = {} - q = queue.Queue() - for a in asteroids: - angles[a] = angle(a[0] - x0, y0 - a[1]) - - for k, v in sorted(angles.items(), key=lambda item: item[1]): - if k in best[2]: - q.put(k) - - destroyed = 1 - while not q.empty(): - #print_map(asteroids, max_x, max_y) - asteroid = q.get() - if destroyed == 200: - return (asteroid, asteroid[0]*100 + asteroid[1]) - asteroids.remove(asteroid) - destroyed += 1 - - # add next asteroid behind to queue - dx = asteroid[0] - x0 - dy = asteroid[1] - y0 - x = x0 - y = y0 - x += dx - y += dy - dx, dy = red((dx, dy)) - x += dx - y += dy - while x < max_x and y < max_y and x >= 0 and y >= 0: - if (x, y) in asteroids: - q.put((x, y)) - break - x += dx - y += dy -if __name__ == "__main__": - import cProfile - - input = open("../input/10","r").readlines() - visualize(input) - #cProfile.run("pt1(input)") - #cProfile.run("pt2(input)") - print(pt1(input)) - print(pt2(input)) |
