Files
advent-of-code-go/2024/day14/day14.py
T
2024-12-27 16:10:36 -05:00

109 lines
3.0 KiB
Python

import re
def part1(input: str, wide: int, tall: int, seconds: int) -> int:
# don't need to model this exactly right? just equate a line, mod by grid size...
# i guess for 100 steps it would've been better to just model it...
quad_counts: list[int] = [0] * 4
for line in input.splitlines():
nums = re.findall(r"-?\d+", line)
assert len(nums) == 4
x = int(nums[0]) + int(nums[2]) * seconds
y = int(nums[1]) + int(nums[3]) * seconds
x %= tall
y %= wide
if x < tall // 2 and y < wide // 2:
# print("top left")
quad_counts[0] += 1
elif x < tall // 2 and y > wide // 2:
# print("top right")
quad_counts[1] += 1
elif x > tall // 2 and y < wide // 2:
# print("bottom left")
quad_counts[2] += 1
elif x > tall // 2 and y > wide // 2:
# print("bottom right")
quad_counts[3] += 1
# else:
# print("on mid line")
# multiply robot count in each quadrant
# does not include robots on mid-lines
return quad_counts[0] * quad_counts[1] * quad_counts[2] * quad_counts[3]
def part2(input: str, wide: int, tall: int) -> int:
# i guess for 100 steps it would've been better to just model it...
# then i could have reused it for part 2...
robots: list[list[int]] = []
for line in input.splitlines():
nums = re.findall(r"-?\d+", line)
assert len(nums) == 4
robots.append([int(x) for x in nums])
for s in range(10_000):
neighbors: set[tuple[int, int]] = set()
matched: set[tuple[int, int]] = set()
for robot in robots:
robot[0] += robot[2]
robot[1] += robot[3]
robot[0] %= tall
robot[1] %= wide
# track how many neighboring robots have been placed so far
# when the number is high enough we probably have some image of a tree
coord = (robot[0], robot[1])
if coord in neighbors:
matched.add(coord)
for dx in [-1, 0, 1]:
for dy in [-1, 0, 1]:
neighbors.add((coord[0] + dx, coord[1] + dy))
if len(matched) >= 250:
print_grid(robots, wide, tall)
# print(len(matched))
return s + 1
raise Exception("should return from loop")
def print_grid(robots: list[list[int]], wide: int, tall: int):
grid: list[list[str]] = []
for _ in range(0, tall):
grid.append([" "] * wide)
for robot in robots:
grid[robot[0]][robot[1]] = "X"
for line in grid:
print("".join(line))
example = """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"""
input = open("input.txt").read().strip()
print(f"part1 example: {part1(example, 7, 11, 100)} want 12")
print(f"part1 example: {part1(input, 103, 101, 100)} want 218965032")
print(f"part2: {part2(input, 103, 101)} want 7037")