2020-12-02 21:34:21 +01:00
|
|
|
# SPDX-License-Identifier: MIT
|
|
|
|
# Copyright (c) 2019 Akumatic
|
|
|
|
#
|
|
|
|
# https://adventofcode.com/2019/day/12
|
2019-12-12 17:12:52 +01:00
|
|
|
|
|
|
|
from itertools import combinations
|
2020-12-02 21:34:21 +01:00
|
|
|
from moon import Moon
|
2019-12-12 17:12:52 +01:00
|
|
|
|
2020-12-02 21:34:21 +01:00
|
|
|
def readFile() -> list:
|
2019-12-12 17:12:52 +01:00
|
|
|
with open(f"{__file__.rstrip('code.py')}input.txt", "r") as f:
|
|
|
|
lines = [line[1:-2].replace(" ", "").split(",") for line in f.readlines()]
|
|
|
|
return [(int(line[0][2:]), int(line[1][2:]), int(line[2][2:])) for line in lines]
|
|
|
|
|
2020-12-02 21:34:21 +01:00
|
|
|
def simulate(moons: list, steps: int = 1):
|
2019-12-12 17:12:52 +01:00
|
|
|
for i in range(steps):
|
|
|
|
for m, n in list(combinations(moons, 2)):
|
|
|
|
m.changeGravity(n)
|
|
|
|
|
|
|
|
for moon in moons:
|
|
|
|
moon.move()
|
2019-12-12 23:38:00 +01:00
|
|
|
|
2020-12-02 21:34:21 +01:00
|
|
|
def lcm(x: int, y: int) -> int:
|
2019-12-12 23:38:00 +01:00
|
|
|
tmp = x * y
|
|
|
|
while y:
|
|
|
|
x, y = y, x % y
|
|
|
|
return tmp // x
|
2019-12-12 17:12:52 +01:00
|
|
|
|
2020-12-02 21:34:21 +01:00
|
|
|
def part1(vals: list) -> int:
|
2019-12-13 01:20:48 +01:00
|
|
|
moons = [Moon(val) for val in vals]
|
2019-12-12 17:12:52 +01:00
|
|
|
simulate(moons, 1000)
|
|
|
|
return sum([moon.energy()[2] for moon in moons])
|
|
|
|
|
2020-12-02 21:34:21 +01:00
|
|
|
def part2(vals: list) -> int:
|
2019-12-12 23:38:00 +01:00
|
|
|
dims = [0, 0, 0]
|
|
|
|
for i in range(3):
|
2019-12-13 01:20:48 +01:00
|
|
|
moons = [Moon(val) for val in vals]
|
|
|
|
oPos = [moon.pos[i] for moon in moons]
|
2019-12-12 23:38:00 +01:00
|
|
|
|
2020-12-02 21:34:21 +01:00
|
|
|
while True:
|
2019-12-12 23:38:00 +01:00
|
|
|
simulate(moons)
|
|
|
|
dims[i] += 1
|
2019-12-13 01:20:48 +01:00
|
|
|
if [moon.pos[i] for moon in moons] == oPos and \
|
|
|
|
[moon.vel[i] for moon in moons] == [0, 0, 0, 0]:
|
2019-12-12 23:38:00 +01:00
|
|
|
break
|
|
|
|
|
|
|
|
return lcm(dims[0], lcm(dims[1], dims[2]))
|
2019-12-12 17:12:52 +01:00
|
|
|
|
|
|
|
def test():
|
|
|
|
moons = [Moon(p) for p in ((-1,0,2), (2,-10,-7), (4,-8,8), (3,5,-1))]
|
|
|
|
simulate(moons, 10)
|
|
|
|
assert sum([moon.energy()[2] for moon in moons]) == 179
|
2019-12-13 01:20:48 +01:00
|
|
|
vpos, vvel = ([2,1,-3],[1,-8,0],[3,-6,1],[2,0,4]), ([-3,-2,1],[-1,1,3],[3,2,-3],[1,-1,-1])
|
2019-12-12 17:12:52 +01:00
|
|
|
for i in range(4):
|
2019-12-13 01:20:48 +01:00
|
|
|
assert vpos[i] == moons[i].pos and vvel[i] == moons[i].vel
|
2019-12-12 17:12:52 +01:00
|
|
|
moons = [Moon(p) for p in ((-8,-10,0), (5,5,10), (2,-7,3), (9,-8,-3))]
|
|
|
|
simulate(moons,100)
|
|
|
|
assert sum([moon.energy()[2] for moon in moons]) == 1940
|
2019-12-12 23:38:00 +01:00
|
|
|
assert part2(((-1,0,2),(2,-10,-7),(4,-8,8),(3,5,-1))) == 2772
|
|
|
|
assert part2(((-8,-10,0),(5,5,10),(2,-7,3),(9,-8,-3))) == 4686774924
|
2019-12-12 17:12:52 +01:00
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
test()
|
|
|
|
vals = readFile()
|
|
|
|
print(f"Part 1: {part1(vals)}")
|
|
|
|
print(f"Part 2: {part2(vals)}")
|