feat: add solution 2025/10
This commit is contained in:
3
data/example/2025/10.txt
Normal file
3
data/example/2025/10.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
[.##.] (3) (1,3) (2) (2,3) (0,2) (0,1) {3,5,4,7}
|
||||
[...#.] (0,2,3,4) (2,3) (0,4) (0,1,2) (1,2,3,4) {7,5,12,7,2}
|
||||
[.###.#] (0,1,2,3,4) (0,3,4) (0,1,2,4,5) (1,2) {10,11,11,5,10,5}
|
||||
@@ -1,2 +1,7 @@
|
||||
# cli
|
||||
python-dotenv==1.2.1
|
||||
requests==2.32.5
|
||||
|
||||
# solutions
|
||||
numpy==2.3.5
|
||||
scipy==1.16
|
||||
|
||||
98
src/solution/year_2025/day_10.py
Normal file
98
src/solution/year_2025/day_10.py
Normal file
@@ -0,0 +1,98 @@
|
||||
import collections
|
||||
import re
|
||||
from typing import Any
|
||||
|
||||
import numpy as np
|
||||
from scipy import optimize
|
||||
|
||||
|
||||
def _parse_input(input_data: str):
|
||||
res: list[tuple[int, list[list[int]], list[int]]] = []
|
||||
|
||||
for line in input_data.splitlines():
|
||||
_state = re.findall(r"\[([.#]*)\]", line)[0]
|
||||
state = sum(1 << i for i, x in enumerate(_state) if x == "#")
|
||||
|
||||
_buttons = re.findall(r"\(([0-9,]*)\)", line)
|
||||
buttons = [[int(n) for n in m.split(",")] for m in _buttons]
|
||||
|
||||
_joltage = re.findall(r" {([0-9,]*)}$", line)[0].strip()
|
||||
joltage = list(map(int, _joltage.split(",")))
|
||||
|
||||
res.append((state, buttons, joltage))
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def _bfs(end: int, neighs: list[int]) -> int:
|
||||
start = 0
|
||||
|
||||
dq = collections.deque([(0, start)])
|
||||
visited = {0}
|
||||
|
||||
while dq:
|
||||
d, p = dq.popleft()
|
||||
|
||||
if p == end:
|
||||
return d
|
||||
|
||||
for n in neighs:
|
||||
np = p ^ n
|
||||
|
||||
if np in visited:
|
||||
continue
|
||||
|
||||
visited.add(np)
|
||||
dq.append((d + 1, np))
|
||||
|
||||
raise ValueError(f"unable to calibrate {end}")
|
||||
|
||||
|
||||
def _milp(vecs: list[list[int]], goal: list[int]) -> int:
|
||||
n = len(goal)
|
||||
m = len(vecs)
|
||||
|
||||
a = np.zeros((n, m), dtype=int)
|
||||
|
||||
for j, vec in enumerate(vecs):
|
||||
for i in vec:
|
||||
a[i][j] = 1
|
||||
|
||||
c = np.ones(m)
|
||||
b = np.array(goal)
|
||||
|
||||
constraints = optimize.LinearConstraint(a, b, b) # type: ignore
|
||||
bounds = optimize.Bounds(0, np.inf)
|
||||
integrality = np.ones(m)
|
||||
|
||||
result = optimize.milp(
|
||||
c,
|
||||
constraints=constraints,
|
||||
bounds=bounds,
|
||||
integrality=integrality,
|
||||
)
|
||||
|
||||
return int(result.fun)
|
||||
|
||||
|
||||
def part_1(input_data: str) -> Any:
|
||||
parsed = _parse_input(input_data)
|
||||
|
||||
s = 0
|
||||
for end, switches, _ in parsed:
|
||||
neighs = [sum(1 << n for n in m) for m in switches]
|
||||
s += _bfs(end, neighs)
|
||||
|
||||
return s
|
||||
|
||||
|
||||
def part_2(input_data: str) -> Any:
|
||||
return sum(_milp(vecs, goal) for _, vecs, goal in _parse_input(input_data))
|
||||
|
||||
|
||||
def test_part_1(example_data):
|
||||
assert part_1(example_data) == 7
|
||||
|
||||
|
||||
def test_part_2(example_data):
|
||||
assert part_2(example_data) == 33
|
||||
Reference in New Issue
Block a user