aoc

commit 3e9018eb7ab58e4e4fc66d9cfd5b455464cbd921

Author: Honza Pokorny <me@honza.ca>

Add 10p1

 010/main.py | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++++++


diff --git a/010/main.py b/010/main.py
new file mode 100644
index 0000000000000000000000000000000000000000..cc16ddf2af995134baf77595e4648008737bf5c7
--- /dev/null
+++ b/010/main.py
@@ -0,0 +1,144 @@
+from copy import deepcopy
+from math import gcd, sqrt
+from itertools import groupby
+
+
+MAP = """.#..#
+.....
+#####
+....#
+...##"""
+
+MAP2 = """......#.#.
+#..#.#....
+..#######.
+.#.#.###..
+.#..#.....
+..#....#.#
+#..#....#.
+.##.#..###
+##...#..#.
+.#....####"""
+
+MAP3 = """#.#...#.#.
+.###....#.
+.#....#...
+##.#.#.#.#
+....#.#.#.
+.##..###.#
+..#...##..
+..##....##
+......#...
+.####.###."""
+
+PUZZLE = """.###..#######..####..##...#
+########.#.###...###.#....#
+###..#...#######...#..####.
+.##.#.....#....##.#.#.....#
+###.#######.###..##......#.
+#..###..###.##.#.#####....#
+#.##..###....#####...##.##.
+####.##..#...#####.#..###.#
+#..#....####.####.###.#.###
+#..#..#....###...#####..#..
+##...####.######....#.####.
+####.##...###.####..##....#
+#.#..#.###.#.##.####..#...#
+..##..##....#.#..##..#.#..#
+##.##.#..######.#..#..####.
+#.....#####.##........#####
+###.#.#######..#.#.##..#..#
+###...#..#.#..##.##..#####.
+.##.#..#...#####.###.##.##.
+...#.#.######.#####.#.####.
+#..##..###...###.#.#..#.#.#
+.#..#.#......#.###...###..#
+#.##.#.#..#.#......#..#..##
+.##.##.##.#...##.##.##.#..#
+#.###.#.#...##..#####.###.#
+#.####.#..#.#.##.######.#..
+.#.#####.##...#...#.##...#."""
+
+
+def get_distance_and_slope(ast1, ast2):
+    x1, y1 = ast1
+    x2, y2 = ast2
+
+    x_, y_ = x2 - x1, y2 - y1
+
+    g = gcd(x_, y_)
+
+    slope = int(x_ / g), int(y_ / g)
+    distance = sqrt(float(x_ ** 2 + y_ ** 2))
+    return slope, distance
+
+
+def parse_map(data):
+    result = []
+
+    for line_i, line in enumerate(data.splitlines()):
+        for c_i, c in enumerate(line):
+            if c == '#':
+                result.append((c_i, line_i))
+
+    return result
+
+
+def get_visible_asteroid_count(ast, asteroid_map):
+    data = []
+
+    for other_ast in asteroid_map:
+        if ast == other_ast:
+            continue
+
+        slope, dist = get_distance_and_slope(ast, other_ast)
+        data.append({
+            'ast': ast,
+            'slope': slope,
+            'distance': dist
+        })
+
+    data = sorted(data, key=lambda x: x['slope'])
+    grouped = groupby(data, lambda x: x['slope'])
+    visible = 0
+
+    for k, g in grouped:
+        visible += 1
+
+    return visible
+
+
+def find_best_asteroid(asteroid_map):
+    x = {}
+    for ast in asteroid_map:
+        num_visible_asts = get_visible_asteroid_count(ast, deepcopy(asteroid_map))
+        x[num_visible_asts] = ast
+
+    keys = list(x.keys())
+    keys.sort()
+    keys.reverse()
+    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)
+
+
+
+
+if __name__ == '__main__':
+    main()