Add day 12 part 1 solution
This commit is contained in:
parent
1342fb40e6
commit
33eb7edfc9
4
day12/input.txt
Normal file
4
day12/input.txt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<x=9, y=13, z=-8>
|
||||||
|
<x=-3, y=16, z=-17>
|
||||||
|
<x=-4, y=11, z=-10>
|
||||||
|
<x=0, y=-2, z=-2>
|
83
day12/py/main.py
Normal file
83
day12/py/main.py
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
import itertools
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
class Moon:
|
||||||
|
INPUT_REGEXP = re.compile(r'(\w)=(-?\d*)')
|
||||||
|
|
||||||
|
def __init__(self, x: int, y: int, z: int):
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.z = z
|
||||||
|
self.x_velocity = 0
|
||||||
|
self.y_velocity = 0
|
||||||
|
self.z_velocity = 0
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def fromInputString(cls, input_str: str) -> 'Moon':
|
||||||
|
matches = re.findall(cls.INPUT_REGEXP, input_str)
|
||||||
|
fields = {}
|
||||||
|
for match in matches:
|
||||||
|
fields[match[0]] = int(match[1])
|
||||||
|
|
||||||
|
return cls(fields['x'], fields['y'], fields['z'])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def potential_energy(self):
|
||||||
|
return abs(self.x) + abs(self.y) + abs(self.z)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def kinetic_energy(self):
|
||||||
|
return abs(self.x_velocity) + abs(self.y_velocity) + abs(self.z_velocity)
|
||||||
|
|
||||||
|
# Applies gravity to this moon and other moon passed in
|
||||||
|
def apply_gravity(self, other: 'Moon') -> None:
|
||||||
|
FIELDS = {
|
||||||
|
'x': 'x_velocity',
|
||||||
|
'y': 'y_velocity',
|
||||||
|
'z': 'z_velocity'
|
||||||
|
}
|
||||||
|
|
||||||
|
for pos_field, velocity_field in FIELDS.items():
|
||||||
|
self_velocity = getattr(self, velocity_field)
|
||||||
|
other_velocity = getattr(other, velocity_field)
|
||||||
|
self_pos = getattr(self, pos_field)
|
||||||
|
other_pos = getattr(other, pos_field)
|
||||||
|
if self_pos > other_pos:
|
||||||
|
setattr(self, velocity_field, self_velocity - 1)
|
||||||
|
setattr(other, velocity_field, other_velocity + 1)
|
||||||
|
elif self_pos < other_pos:
|
||||||
|
setattr(self, velocity_field, self_velocity + 1)
|
||||||
|
setattr(other, velocity_field, other_velocity - 1)
|
||||||
|
|
||||||
|
# Update all of the positions based on the stored velocities
|
||||||
|
def update_position(self) -> None:
|
||||||
|
self.x += self.x_velocity
|
||||||
|
self.y += self.y_velocity
|
||||||
|
self.z += self.z_velocity
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return (f'pos=<x={self.x}, y={self.y}, z={self.z}> ' +
|
||||||
|
f'vel=<x={self.x_velocity}, y={self.y_velocity}, z={self.z_velocity}>')
|
||||||
|
|
||||||
|
|
||||||
|
def part1(moons: Moon) -> int:
|
||||||
|
for i in range(1000):
|
||||||
|
for moon_1, moon_2 in itertools.combinations(moons, 2):
|
||||||
|
moon_1.apply_gravity(moon_2)
|
||||||
|
for moon in moons:
|
||||||
|
moon.update_position()
|
||||||
|
|
||||||
|
return sum(moon.kinetic_energy * moon.potential_energy for moon in moons)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
print("Usage: ./main.py in_file")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
with open(sys.argv[1]) as f:
|
||||||
|
moons = [Moon.fromInputString(line.rstrip()) for line in f if len(line.rstrip()) > 0]
|
||||||
|
|
||||||
|
print(part1(moons))
|
4
day12/sample.txt
Normal file
4
day12/sample.txt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<x=-1, y=0, z=2>
|
||||||
|
<x=2, y=-10, z=-7>
|
||||||
|
<x=4, y=-8, z=8>
|
||||||
|
<x=3, y=5, z=-1>
|
4
day12/sample2.txt
Normal file
4
day12/sample2.txt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<x=-8, y=-10, z=0>
|
||||||
|
<x=5, y=5, z=10>
|
||||||
|
<x=2, y=-7, z=3>
|
||||||
|
<x=9, y=-8, z=-3>
|
Loading…
Reference in a new issue