mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 21:00:31 +01:00
Implement 2024 day 14
This commit is contained in:
73
2024/src/aoc/days/day14.py
Normal file
73
2024/src/aoc/days/day14.py
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
import itertools
|
||||||
|
import math
|
||||||
|
import re
|
||||||
|
|
||||||
|
import numpy
|
||||||
|
|
||||||
|
from . import SeparateRunner
|
||||||
|
|
||||||
|
NASTY_REGEX = re.compile(r"p=(-?\d+),(-?\d+) v=(-?\d+),(-?\d+)")
|
||||||
|
|
||||||
|
|
||||||
|
class DayRunner(SeparateRunner):
|
||||||
|
@classmethod
|
||||||
|
def part1(cls, input: str, width: int = 101, height: int = 103) -> int:
|
||||||
|
points = NASTY_REGEX.findall(input)
|
||||||
|
|
||||||
|
quadrants = [0] * 4
|
||||||
|
|
||||||
|
x_middle = width // 2
|
||||||
|
y_middle = height // 2
|
||||||
|
|
||||||
|
for point in points:
|
||||||
|
x, y, dx, dy = map(int, point)
|
||||||
|
|
||||||
|
rx = ((x + dx * 100) % width + width) % width
|
||||||
|
ry = ((y + dy * 100) % height + height) % height
|
||||||
|
|
||||||
|
match rx:
|
||||||
|
case _ if rx < x_middle:
|
||||||
|
xq = 0
|
||||||
|
case _ if rx > x_middle:
|
||||||
|
xq = 1
|
||||||
|
case _:
|
||||||
|
continue
|
||||||
|
|
||||||
|
match ry:
|
||||||
|
case _ if ry < y_middle:
|
||||||
|
yq = 0
|
||||||
|
case _ if ry > y_middle:
|
||||||
|
yq = 1
|
||||||
|
case _:
|
||||||
|
continue
|
||||||
|
|
||||||
|
quadrants[2 * yq + xq] += 1
|
||||||
|
|
||||||
|
return math.prod(quadrants)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def part2(cls, input: str) -> int:
|
||||||
|
width = 101
|
||||||
|
height = 103
|
||||||
|
|
||||||
|
points = NASTY_REGEX.findall(input)
|
||||||
|
points_fast = numpy.array([list(map(int, point)) for point in points])
|
||||||
|
|
||||||
|
positions = points_fast[:, 0:2]
|
||||||
|
velocities = points_fast[:, 2:]
|
||||||
|
|
||||||
|
target = len(velocities)
|
||||||
|
|
||||||
|
# Assumption: when the easter egg happens, no robots overlap, and this is the
|
||||||
|
# only time this happens. There is no reason this should work but it does.
|
||||||
|
mod_base = numpy.array([width, height])
|
||||||
|
for i in itertools.count(1):
|
||||||
|
positions += velocities
|
||||||
|
|
||||||
|
positions %= mod_base
|
||||||
|
positions += mod_base
|
||||||
|
positions %= mod_base
|
||||||
|
|
||||||
|
if len(numpy.unique(positions, axis=0)) == target:
|
||||||
|
# TODO: print the Christmas tree, Eric prepared it for us so nicely
|
||||||
|
return i
|
||||||
12
2024/tests/samples/14.txt
Normal file
12
2024/tests/samples/14.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
p=0,4 v=3,-3
|
||||||
|
p=6,3 v=-1,-3
|
||||||
|
p=10,3 v=-1,2
|
||||||
|
p=2,0 v=2,-1
|
||||||
|
p=0,0 v=1,3
|
||||||
|
p=3,0 v=-2,-2
|
||||||
|
p=7,6 v=-1,-3
|
||||||
|
p=3,0 v=-1,-2
|
||||||
|
p=9,3 v=2,3
|
||||||
|
p=7,3 v=-1,2
|
||||||
|
p=2,4 v=2,-3
|
||||||
|
p=9,5 v=-3,-3
|
||||||
7
2024/tests/test_day14.py
Normal file
7
2024/tests/test_day14.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
from aoc.days.day14 import DayRunner
|
||||||
|
|
||||||
|
from . import get_data
|
||||||
|
|
||||||
|
|
||||||
|
def test_sample_part1() -> None:
|
||||||
|
assert DayRunner.part1(get_data(14), width=11, height=7) == 12
|
||||||
Reference in New Issue
Block a user