109 lines
2.4 KiB
Python
109 lines
2.4 KiB
Python
from itertools import combinations
|
|
from math import lcm
|
|
|
|
from output import answer, ints # , matrix, D, DD, ADJ, ints, mhd, mdbg, vdbg
|
|
|
|
n = 12
|
|
title = "The N-Body Problem"
|
|
|
|
|
|
@answer(1, "Answer is {}")
|
|
def part_1(outputs):
|
|
return outputs[0]
|
|
|
|
|
|
@answer(2, "Actually, answer is {}")
|
|
def part_2(outputs):
|
|
return outputs[1]
|
|
|
|
|
|
def solve(data):
|
|
M = [[ints(l), [0, 0, 0]] for l in data.splitlines()]
|
|
|
|
def G(m):
|
|
def U(x, y):
|
|
if x > y:
|
|
return -1
|
|
elif x < y:
|
|
return 1
|
|
return 0
|
|
|
|
for i, j in combinations(range(len(m)), r=2):
|
|
m1 = m[i]
|
|
m2 = m[j]
|
|
g1, v1 = m1
|
|
g2, v2 = m2
|
|
x1, y1, z1 = g1
|
|
x2, y2, z2 = g2
|
|
a1, b1, c1 = v1
|
|
a2, b2, c2 = v2
|
|
m[i] = [
|
|
g1,
|
|
[
|
|
a1 + U(x1, x2),
|
|
b1 + U(y1, y2),
|
|
c1 + U(z1, z2),
|
|
],
|
|
]
|
|
m[j] = [
|
|
g2,
|
|
[
|
|
a2 + U(x2, x1),
|
|
b2 + U(y2, y1),
|
|
c2 + U(z2, z1),
|
|
],
|
|
]
|
|
|
|
return m
|
|
|
|
def V(m):
|
|
nm = []
|
|
for gv in m:
|
|
g, v = gv
|
|
x1, y1, z1 = g
|
|
x2, y2, z2 = v
|
|
nm.append(
|
|
[
|
|
[
|
|
x1 + x2,
|
|
y1 + y2,
|
|
z1 + z2,
|
|
],
|
|
v,
|
|
]
|
|
)
|
|
return nm
|
|
|
|
P1 = M.copy()
|
|
for _ in range(1000):
|
|
P1 = V(G(P1))
|
|
p1 = sum(sum(map(abs, p)) * sum(map(abs, k)) for p, k in P1)
|
|
P2 = M.copy()
|
|
p2 = []
|
|
for i, igv in enumerate(zip(*[g for g, v in P2])):
|
|
igv = [(g, 0) for g in igv]
|
|
Q = P2.copy()
|
|
C = 0
|
|
while True:
|
|
Q = V(G(Q))
|
|
C += 1
|
|
sg = list(zip(*[g for g, v in Q]))[i]
|
|
sv = list(zip(*[v for g, v in Q]))[i]
|
|
if list(zip(sg, sv)) == igv:
|
|
p2.append(C)
|
|
break
|
|
p2 = lcm(*p2)
|
|
return p1, p2
|
|
|
|
|
|
if __name__ == "__main__":
|
|
with open("./input/12.txt", "r") as f:
|
|
inp = f.read().strip()
|
|
|
|
inp = solve(inp)
|
|
|
|
a = part_1(inp)
|
|
b = part_2(inp)
|
|
|
|
assert a == 12466
|
|
assert b == 360689156787864
|