aoc

commit 1fbf37788f55be2916775c3f6a2800d5d332497b

Author: Honza Pokorny <me@honza.ca>

10p2

 010/main.py | 116 ++++++++++++++++++++++++++++++++----------------------


diff --git a/010/main.py b/010/main.py
index cc16ddf2af995134baf77595e4648008737bf5c7..084bc2a1fbf1eb02c56dafd24fc78bd3705e6eec 100644
--- a/010/main.py
+++ b/010/main.py
@@ -1,36 +1,8 @@
 from copy import deepcopy
-from math import gcd, sqrt
+from math import gcd, atan2, pi
 from itertools import groupby
 
 
-MAP = """.#..#
-.....
-#####
-....#
-...##"""
-
-MAP2 = """......#.#.
-#..#.#....
-..#######.
-.#.#.###..
-.#..#.....
-..#....#.#
-#..#....#.
-.##.#..###
-##...#..#.
-.#....####"""
-
-MAP3 = """#.#...#.#.
-.###....#.
-.#....#...
-##.#.#.#.#
-....#.#.#.
-.##..###.#
-..#...##..
-..##....##
-......#...
-.####.###."""
-
 PUZZLE = """.###..#######..####..##...#
 ########.#.###...###.#....#
 ###..#...#######...#..####.
@@ -65,12 +37,13 @@     x1, y1 = ast1
     x2, y2 = ast2
 
     x_, y_ = x2 - x1, y2 - y1
+    x_, y_ = x1 - x2, y1 - y2
 
     g = gcd(x_, y_)
 
     slope = int(x_ / g), int(y_ / g)
-    distance = sqrt(float(x_ ** 2 + y_ ** 2))
-    return slope, distance
+    distance = float(x_ ** 2 + y_ ** 2)
+    return None, distance
 
 
 def parse_map(data):
@@ -94,7 +67,6 @@
         slope, dist = get_distance_and_slope(ast, other_ast)
         data.append({
             'ast': ast,
-            'slope': slope,
             'distance': dist
         })
 
@@ -108,6 +80,68 @@
     return visible
 
 
+def rem(self, rhs):
+    if rhs == 0:
+        raise Exception('zerooo')
+
+    r = self % rhs
+
+    if r < 0:
+        if rhs < 0:
+            return r - rhs
+        else:
+            return r + rhs
+    else:
+        return r
+
+
+def get_angle(a, b):
+    y = b[0] - a[0]
+    x = a[1] - b[1]
+    angle = atan2(y, x)
+
+    a = rem(angle, pi * 2.0)
+    prec = 100000
+
+    return int(a * prec)
+
+
+def get_visible_asteroids_by_angle(ast, asteroid_map):
+    asteroids = []
+
+    for other_ast in asteroid_map:
+        if ast == other_ast:
+            continue
+
+        _, dist = get_distance_and_slope(ast, other_ast)
+        asteroids.append({
+            'ast': other_ast,
+            # 'angle': get_angle(ast, other_ast),
+            'distance': dist
+        })
+
+    asteroids = sorted(asteroids, key=lambda x: x['distance'])
+    sort_keys = {}
+    things = []
+
+    for i, asteroid in enumerate(asteroids):
+        angle = get_angle(ast, asteroid['ast'])
+        previous_asteroids = filter(
+            lambda x: angle == get_angle(ast, x['ast']),
+            asteroids[:i]
+        )
+        rank = len(list(previous_asteroids))
+
+        s = "%s-%s" % asteroid['ast']
+        sort_keys[s] = (rank, angle, asteroid['ast'])
+        things.append(s)
+
+    things = sorted(things, key=lambda x: sort_keys[x])
+    two_hundredth = things[199]
+    _, _, ast = sort_keys[two_hundredth]
+    print(ast[0] * 100 + ast[1])
+
+
 def find_best_asteroid(asteroid_map):
     x = {}
     for ast in asteroid_map:
@@ -121,23 +155,11 @@     return x[keys[0]], keys[0]
 
 
 def main():
-    asteroid_map = parse_map(MAP)
-    _, num = find_best_asteroid(asteroid_map)
-    assert num == 8, num
-
-    asteroid_map = parse_map(MAP2)
-    _, num = find_best_asteroid(asteroid_map)
-    assert num == 33, num
-
-    asteroid_map = parse_map(MAP3)
-    _, num = find_best_asteroid(asteroid_map)
-    assert num == 35, num
-
     asteroid_map = parse_map(PUZZLE)
-    _, num = find_best_asteroid(asteroid_map)
-    print(num)
+    # station, visible = find_best_asteroid(asteroid_map)
+    station = (17, 23)
 
-
+    get_visible_asteroids_by_angle(station, asteroid_map)
 
 
 if __name__ == '__main__':