86 lines
2.2 KiB
Python
86 lines
2.2 KiB
Python
from tools.aoc import AOCDay
|
|
from tools.coordinate import Coordinate, DistanceAlgorithm
|
|
from typing import Any
|
|
|
|
|
|
ZERO = Coordinate(0, 0, 0)
|
|
|
|
|
|
class Particle:
|
|
def __init__(self, pos: Coordinate, vel: Coordinate, acc: Coordinate):
|
|
self.pos = pos
|
|
self.vel = vel
|
|
self.acc = acc
|
|
|
|
def move(self):
|
|
self.vel += self.acc
|
|
self.pos += self.vel
|
|
|
|
def dist(self):
|
|
return self.pos.getDistanceTo(ZERO, algorithm=DistanceAlgorithm.MANHATTAN, includeDiagonals=False)
|
|
|
|
|
|
class Day(AOCDay):
|
|
inputs = [
|
|
[
|
|
(0, "input20_test"),
|
|
(457, "input20")
|
|
],
|
|
[
|
|
(1, "input20_test2"),
|
|
(448, "input20")
|
|
]
|
|
]
|
|
|
|
def getParticles(self) -> list:
|
|
particles = []
|
|
for line in self.getInput():
|
|
p, v, a = line.split(", ")
|
|
p = Coordinate(*map(int, p[3:-1].split(",")))
|
|
v = Coordinate(*map(int, v[3:-1].split(",")))
|
|
a = Coordinate(*map(int, a[3:-1].split(",")))
|
|
|
|
particles.append(Particle(p, v, a))
|
|
|
|
return particles
|
|
|
|
def part1(self) -> Any:
|
|
particles = self.getParticles()
|
|
closest = 0
|
|
last_closest = list(range(-1, -1000, -1))
|
|
while len(set(last_closest)) != 1:
|
|
last_closest.append(closest)
|
|
last_closest.pop(0)
|
|
min_dist = 10e9
|
|
for i, p in enumerate(particles):
|
|
p.move()
|
|
if p.dist() < min_dist:
|
|
closest = i
|
|
min_dist = p.dist()
|
|
|
|
return closest
|
|
|
|
def part2(self) -> Any:
|
|
particles = self.getParticles()
|
|
for _ in range(1000):
|
|
pos_cache = {}
|
|
new_particles = []
|
|
for i, p in enumerate(particles.copy()):
|
|
p.move()
|
|
if p.pos not in pos_cache:
|
|
new_particles.append(p)
|
|
pos_cache[p.pos] = len(new_particles) - 1
|
|
else:
|
|
if pos_cache[p.pos] >= 0:
|
|
new_particles.pop(pos_cache[p.pos])
|
|
pos_cache[p.pos] = -1
|
|
|
|
particles = new_particles
|
|
|
|
return len(particles)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
day = Day(2017, 20)
|
|
day.run(verbose=True)
|