mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 12:50:32 +01:00
Compare commits
2 Commits
c8ab67d145
...
98983f622c
| Author | SHA1 | Date | |
|---|---|---|---|
| 98983f622c | |||
| 4a7305d7eb |
80
2024/src/aoc/days/day14.py
Normal file
80
2024/src/aoc/days/day14.py
Normal file
@@ -0,0 +1,80 @@
|
||||
import itertools
|
||||
import math
|
||||
import re
|
||||
import sys
|
||||
|
||||
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:
|
||||
grid = [[" "] * width for _ in range(height)]
|
||||
|
||||
for x, y in positions:
|
||||
grid[y][x] = "#"
|
||||
|
||||
tree = "\n".join(map((lambda x: "".join(x)), grid))
|
||||
print(tree, file=sys.stderr)
|
||||
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