Files
advent-of-code-2024/day14/code.py

124 lines
3.0 KiB
Python
Raw Normal View History

2025-01-04 18:22:58 +03:00
import sys
sys.path.append('../aoclib')
from aoclib import Input
import re
from collections import defaultdict
class Robot:
def __init__(self, x, y, xv, yv: int):
self.x = x
self.y = y
self.xv = xv
self.yv = yv
def step(self, max_x, max_y, n=1):
for _ in range(n):
self.x = (self.x + self.xv) % max_x
self.y = (self.y + self.yv) % max_y
class Map:
def __init__(self, x, y: int, robots: list[Robot]):
self.x = x
self.y = y
self.robots = robots
self.steps = 0
def __str__(self):
field = [[0 for _ in range(self.x)] for _ in range(self.y)]
for r in self.robots:
field[r.y][r.x] += 1
return '\n'.join(''.join('*' if x>0 else ' ' for x in l) for l in field)
def step(self, n=1):
for r in self.robots:
r.step(self.x, self.y, n)
self.steps += n
def solve1(self) -> int:
self.step(100)
_x, _y = self.x // 2, self.y // 2
field = [[0 for _ in range(self.x)] for _ in range(self.y)]
for r in self.robots:
field[r.y][r.x] += 1
q1 = 0
for y in range(0, _y):
for x in range(0, _x):
q1 += field[y][x]
q2 = 0
for y in range(0, _y):
for x in range(_x+1, len(field[0])):
q2 += field[y][x]
q3 = 0
for y in range(_y+1, len(field)):
for x in range(0, _x):
q3 += field[y][x]
q4 = 0
for y in range(_y+1, len(field)):
for x in range(_x+1, len(field[0])):
q4 += field[y][x]
return q1*q2*q3*q4
def solve2(self) -> int:
while not self.has_n_adjacent(20):
self.step()
return self.steps
def has_n_adjacent(self, n=10):
d = defaultdict(set)
for r in self.robots:
d[r.x].add(r.y)
def search(l, n):
for i in range(len(l) - n):
if l[i+n-1] - l[i] == n-1:
return True
return False
for x in d:
l = sorted(list(d[x]))
if search(l, n):
return True
return False
def parse_input(lines: list[str], x, y: int):
rrx = re.compile(r'p=(\d+),(\d+) v=(-*\d+),(-*\d+)')
robots = list()
for l in lines:
m = rrx.search(l)
r = Robot(int(m.group(1)), int(m.group(2)), int(m.group(3)), int(m.group(4)))
robots.append(r)
m = Map(x, y, robots)
return m
def solve1(lines: list[str]):
#m = parse_input(lines, 11, 7)
m = parse_input(lines, 101, 103)
return m.solve1()
def solve2(lines: list[str]):
m = parse_input(lines, 101, 103)
m.solve2()
print(m)
return m.steps
if __name__ == '__main__':
#lines = Input('input_test.txt').lines()
lines = Input('input.txt').lines()
#part 1
print('part 1:', solve1(lines)) # 27157
#part 2
print('part 2:', solve2(lines)) # 8258