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()