Roderic Day 5 роки тому
джерело
коміт
2d76ec198e
1 змінених файлів з 51 додано та 0 видалено
  1. +51
    -0
      y2019/p12.py

+ 51
- 0
y2019/p12.py Переглянути файл

import functools
import itertools
import re
import sys
from math import gcd


def calculate_energy(moons, vels):
return sum(
sum(abs(p) for p in moon) * sum(abs(v) for v in vel)
for moon, vel in zip(moons, vels)
)


def simulate(text, axes=slice(0, 3), lim=None):
g = (int(n) for n in re.findall(r'-?\d+', text))
moons = [point[axes] for point in zip(*[g] * 3)]
vels = [[0, 0, 0] for m in moons]

seen = set()
for step in itertools.count():
if lim is not None and step >= lim:
break

for (i, A), (j, B) in itertools.combinations(enumerate(moons), 2):
dV = [max(a < b, 0) or -max(b < a, 0) for a, b in zip(A, B)]
vels[i] = [v + d for v, d in zip(vels[i], dV)]
vels[j] = [v - d for v, d in zip(vels[j], dV)]

for i, moon in enumerate(moons):
moons[i] = [p + v for p, v in zip(moons[i], vels[i])]

key = str(moons) + str(vels)
if key in seen:
break
seen.add(key)

return step, calculate_energy(moons, vels)


text = sys.stdin.read()

_, energy = simulate(text, lim=1000)
print(energy)

nX, _ = simulate(text, axes=slice(0, 1))
nY, _ = simulate(text, axes=slice(1, 2))
nZ, _ = simulate(text, axes=slice(2, 3))
gcds = {gcd(p, q) for p, q in itertools.combinations([nX, nY, nZ], 2)}
lcm = functools.reduce(int.__mul__, gcds)
print(nX * nY * nZ // lcm)

Завантаження…
Відмінити
Зберегти