75 lines
2.5 KiB
Python
75 lines
2.5 KiB
Python
import itertools as it
|
|
import operator as op
|
|
from math import prod
|
|
from typing import Any, Iterator
|
|
|
|
import numpy as np
|
|
import parse # pyright: ignore[reportMissingTypeStubs]
|
|
|
|
from ..base import BaseSolver
|
|
|
|
|
|
class Solver(BaseSolver):
|
|
def solve(self, input: str) -> Iterator[Any]:
|
|
positions: list[tuple[int, int]] = []
|
|
velocities: list[tuple[int, int]] = []
|
|
|
|
for line in input.splitlines():
|
|
r = parse.parse("p={x:d},{y:d} v={vx:d},{vy:d}", line) # type: ignore
|
|
positions.append((r["y"], r["x"])) # type: ignore
|
|
velocities.append((r["vy"], r["vx"])) # type: ignore
|
|
|
|
n_rows, n_cols = 103, 101
|
|
if len(positions) < 20:
|
|
n_rows, n_cols = 7, 11
|
|
|
|
n_rounds = 100
|
|
new_positions = [
|
|
((row + v_row * n_rounds) % n_rows, (col + v_col * n_rounds) % n_cols)
|
|
for (row, col), (v_row, v_col) in zip(positions, velocities, strict=True)
|
|
]
|
|
|
|
midrow = n_rows // 2
|
|
midcol = n_cols // 2
|
|
|
|
yield prod(
|
|
(
|
|
sum(opr(row, midrow) and opc(col, midcol) for row, col in new_positions)
|
|
for opr, opc in it.product((op.gt, op.lt), repeat=2)
|
|
)
|
|
)
|
|
|
|
new_positions = positions.copy()
|
|
for rnd in self.progress.wrap(range(10000)):
|
|
new_positions = [
|
|
((row + v_row) % n_rows, (col + v_col) % n_cols)
|
|
for (row, col), (v_row, v_col) in zip(
|
|
new_positions, velocities, strict=True
|
|
)
|
|
]
|
|
m = [[False for _ in range(n_cols)] for _ in range(n_rows)]
|
|
for row, col in new_positions:
|
|
m[row][col] = True
|
|
|
|
found = False
|
|
for row in m:
|
|
if sum(row) <= 10:
|
|
continue
|
|
if any(all(row[i : i + 10]) for i in range(n_cols - 10)):
|
|
if self.files:
|
|
self.files.create(
|
|
f"result_{rnd+1}.txt",
|
|
"\n".join(
|
|
"".join("#" if m[i][j] else "." for j in range(n_cols))
|
|
for i in range(n_rows)
|
|
).encode(),
|
|
True,
|
|
)
|
|
self.files.image(f"result_{rnd+1}.png", np.array(m))
|
|
yield rnd + 1
|
|
# found = True
|
|
break
|
|
|
|
if found:
|
|
break
|