This commit is contained in:
parent
8969ea895f
commit
323f810fcd
88
src/holt59/aoc/2015/day24.py
Normal file
88
src/holt59/aoc/2015/day24.py
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
from typing import Any, Iterator, TypeAlias
|
||||||
|
|
||||||
|
from ..base import BaseSolver
|
||||||
|
|
||||||
|
TupleOfInts: TypeAlias = tuple[int, ...]
|
||||||
|
|
||||||
|
|
||||||
|
def check_n_groups(
|
||||||
|
target: int, groups: tuple[TupleOfInts, ...], numbers: TupleOfInts
|
||||||
|
) -> bool:
|
||||||
|
n_groups = len(groups)
|
||||||
|
groups_s = tuple(sum(group) for group in groups)
|
||||||
|
|
||||||
|
if all(target == group_s for group_s in groups_s):
|
||||||
|
return not numbers
|
||||||
|
|
||||||
|
if not numbers:
|
||||||
|
return False
|
||||||
|
|
||||||
|
head, *tail_l = numbers
|
||||||
|
tail, tail_s = tuple(tail_l), sum(tail_l)
|
||||||
|
|
||||||
|
return any(
|
||||||
|
groups_s[i] + head <= target
|
||||||
|
and sum(groups_s[j] for j in range(len(groups)) if i != j) + tail_s
|
||||||
|
>= (n_groups - 1) * target
|
||||||
|
and check_n_groups(
|
||||||
|
target, groups[:i] + ((groups[i] + (head,)),) + groups[i + 1 :], tail
|
||||||
|
)
|
||||||
|
for i in range(len(groups))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def enumerate_single_subset(
|
||||||
|
target: int, numbers: TupleOfInts
|
||||||
|
) -> Iterator[tuple[int, TupleOfInts, TupleOfInts]]:
|
||||||
|
"""
|
||||||
|
Enumerate subset of numbers whose sum equals target.
|
||||||
|
|
||||||
|
Subset are enumerated in increasing order of length, then product (quantum value).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
target: Target for the sum of the subset.
|
||||||
|
numbers: Tuple of integers to find the subset from.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A generator (quantum, subset, remaining) where subset if the subset of numbers
|
||||||
|
whose sum equals target, quantum the product of the subset, and remaining the
|
||||||
|
remaining numbers.
|
||||||
|
"""
|
||||||
|
groups: list[tuple[int, TupleOfInts, TupleOfInts]] = [(1, (), numbers)]
|
||||||
|
|
||||||
|
for _ in range(len(numbers)):
|
||||||
|
new_groups: list[tuple[int, TupleOfInts, TupleOfInts]] = []
|
||||||
|
|
||||||
|
for g_quantum, group, remaining in groups:
|
||||||
|
sg = sum(group)
|
||||||
|
for i in range(len(remaining)):
|
||||||
|
if group and remaining[i] <= group[-1]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
uv = remaining[:i] + remaining[i + 1 :]
|
||||||
|
kv = g_quantum * remaining[i], group + (remaining[i],), uv
|
||||||
|
|
||||||
|
if sg + remaining[i] == target:
|
||||||
|
yield kv
|
||||||
|
elif sg + remaining[i] < target:
|
||||||
|
new_groups.append(kv)
|
||||||
|
|
||||||
|
groups = new_groups
|
||||||
|
|
||||||
|
|
||||||
|
def find_min_quantum(numbers: tuple[int, ...], n_groups: int):
|
||||||
|
return next(
|
||||||
|
g_quantum
|
||||||
|
for g_quantum, group_1v2, group_234v2 in enumerate_single_subset(
|
||||||
|
sum(numbers) // n_groups, numbers
|
||||||
|
)
|
||||||
|
if check_n_groups(sum(group_1v2), ((),) * (n_groups - 1), group_234v2)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Solver(BaseSolver):
|
||||||
|
def solve(self, input: str) -> Iterator[Any]:
|
||||||
|
numbers = tuple(map(int, input.split()))
|
||||||
|
|
||||||
|
yield find_min_quantum(numbers, 3)
|
||||||
|
yield find_min_quantum(numbers, 4)
|
28
src/holt59/aoc/inputs/holt59/2015/day24.txt
Normal file
28
src/holt59/aoc/inputs/holt59/2015/day24.txt
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
1
|
||||||
|
3
|
||||||
|
5
|
||||||
|
11
|
||||||
|
13
|
||||||
|
17
|
||||||
|
19
|
||||||
|
23
|
||||||
|
29
|
||||||
|
31
|
||||||
|
41
|
||||||
|
43
|
||||||
|
47
|
||||||
|
53
|
||||||
|
59
|
||||||
|
61
|
||||||
|
67
|
||||||
|
71
|
||||||
|
73
|
||||||
|
79
|
||||||
|
83
|
||||||
|
89
|
||||||
|
97
|
||||||
|
101
|
||||||
|
103
|
||||||
|
107
|
||||||
|
109
|
||||||
|
113
|
10
src/holt59/aoc/inputs/tests/2015/day24.txt
Normal file
10
src/holt59/aoc/inputs/tests/2015/day24.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
5
|
||||||
|
7
|
||||||
|
8
|
||||||
|
9
|
||||||
|
10
|
||||||
|
11
|
Loading…
Reference in New Issue
Block a user