Solve 2019:12 "The N-Body Problem"
Also, fix bug in ints() helper.
This commit is contained in:
parent
051c3f3ebd
commit
d01b4aa0f8
2 changed files with 110 additions and 1 deletions
|
|
@ -54,7 +54,7 @@ def answer(part_index, fmt_string):
|
|||
|
||||
def ints(s):
|
||||
"""Extract all integers from a string"""
|
||||
return [int(n) for n in re.findall(r"\d+", s)]
|
||||
return [int(n) for n in re.findall(r"-?\d+", s)]
|
||||
|
||||
|
||||
def mhd(a, b):
|
||||
|
|
|
|||
109
2019-python/output/day_12.py
Normal file
109
2019-python/output/day_12.py
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
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
|
||||
Loading…
Add table
Reference in a new issue