Skip to content

Instantly share code, notes, and snippets.

@erikaderstedt
Created December 12, 2019 08:11
Show Gist options
  • Save erikaderstedt/a7de688e69444f0f0ac2d895598c6e8f to your computer and use it in GitHub Desktop.
Save erikaderstedt/a7de688e69444f0f0ac2d895598c6e8f to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# -*- coding: utf8 -*-
import numpy as np
from re import compile
from math import gcd
def minsta_gemensamma(a, b):
return abs(a*b) // gcd(a, b)
data = open('12.in','r').read()
x = compile(r"<x=(-?\d+), y=(-?\d+), z=(-?\d+)>")
moons = np.array([[int(a) for a in x.match(m).groups()] for m in data.split("\n") if x.match(m) is not None], dtype=int)
velocities = np.zeros(moons.shape, dtype=int)
initial_position = moons.copy()
# Since the calculation is reversible, then if it repeats it must be a closed loop
# with no branches. Therefore the first repeated step must be the initial step.
steps = 0
p1done = False
p2axes_complete = [False,False,False]
periods = 1
while (not p1done) or (not all(p2axes_complete)):
for i in range(len(moons)):
for j in range(i+1, len(moons)):
diff = np.sign(moons[i,:] - moons[j,:])
velocities[i,:] = velocities[i,:] - diff
velocities[j,:] = velocities[j,:] + diff
steps = steps + 1
moons = moons + velocities
if steps == 1000:
print("Pt 1:", np.sum(np.sum(np.abs(moons), axis=1)*np.sum(np.abs(velocities), axis=1)))
p1done = True
for axis in range(3):
if p2axes_complete[axis]:
continue
if np.all(moons[:,axis] == initial_position[:,axis]) and np.all(velocities[:,axis] == 0):
p2axes_complete[axis] = True
print("Axis",axis,"complete at", steps,"steps")
periods = minsta_gemensamma(periods, steps)
if all(p2axes_complete):
print("Pt 2:", periods)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment