From 3c109418357f608fdcd0d6e67c913d103278692e Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Thu, 12 Dec 2019 11:23:09 +0100 Subject: [PATCH] 2019: d12: ex2: add solution --- 2019/d12/ex2/ex2.py | 77 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100755 2019/d12/ex2/ex2.py diff --git a/2019/d12/ex2/ex2.py b/2019/d12/ex2/ex2.py new file mode 100755 index 0000000..64bb73d --- /dev/null +++ b/2019/d12/ex2/ex2.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python + + +import re +import sys +from copy import deepcopy +from dataclasses import dataclass +from math import gcd +from typing import List + + +@dataclass +class Position: + x: int + y: int + z: int + + +def line_to_pos(l: str) -> Position: + "" + regex = r"[^,]*), y=(?P[^,]*), z=(?P[^,]*)>" + match = re.search(regex, l) + assert match is not None # Sanity check + return Position(*(int(match.group(g)) for g in ("x", "y", "z"))) + + +def lcm(a: int, b: int, c: int) -> int: + def lcm_2(a: int, b: int) -> int: + return abs(a * b) // gcd(a, b) + + return lcm_2(lcm_2(a, b), c) + + +def main() -> None: + asteroids = [line_to_pos(line) for line in sys.stdin.readlines()] + velocities = [Position(0, 0, 0) for __ in asteroids] + + cycles: List[int] = [] + for attr in ("x", "y", "z"): + all_prev_pos = [deepcopy(asteroids)] + all_prev_vel = [deepcopy(velocities)] + i = 0 + + found = False + while not found: + i += 1 + for orig, v in zip(asteroids, velocities): + for other in asteroids: + if orig.x != other.x: + v.x += 1 if orig.x < other.x else -1 + if orig.y != other.y: + v.y += 1 if orig.y < other.y else -1 + if orig.z != other.z: + v.z += 1 if orig.z < other.z else -1 + + for asteroid, v in zip(asteroids, velocities): + asteroid.x += v.x + asteroid.y += v.y + asteroid.z += v.z + + for old_pos, old_vel in zip(all_prev_pos, all_prev_vel): + if all( + n.__getattribute__(attr) == o.__getattribute__(attr) + for n, o in zip(asteroids, old_pos) + ) and all( + n.__getattribute__(attr) == o.__getattribute__(attr) + for n, o in zip(velocities, old_vel) + ): + found = True + + cycles.append(i) + + print(lcm(*cycles)) + + +if __name__ == "__main__": + main()