summaryrefslogtreecommitdiffstats
path: root/17/solution.py
blob: fa3e9850d243328c29314ef453ce841c08635446 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from collections import Counter
from functools import cache

def part1(containers: list[int]) -> int:
    @cache
    def combinations(index: int, remaining: int) -> int:
        if index == len(containers):
            return 1 if remaining == 0 else 0
        return combinations(index + 1, remaining) + combinations(index + 1, remaining - containers[index])
    return combinations(0, 150)

def part2(containers: list[int]) -> int:
    @cache
    def min_used(index: int, remaining: int, used: int) -> int | float:
        if index == len(containers):
            return used if remaining == 0 else float('inf')
        return min(min_used(index + 1, remaining, used), min_used(index + 1, remaining - containers[index], used + 1))
    min_used = min_used(0, 150, 0)
    @cache
    def count_min(index: int, remaining: int, used: int) -> int | float:
        if index == len(containers):
            return 1 if (remaining == 0 and used == min_used) else 0
        return count_min(index + 1, remaining, used) + count_min(index + 1, remaining - containers[index], used + 1)
    return count_min(0, 150, 0)

if __name__ == '__main__':
    with open('input') as f:
        containers = list(sorted((int(line.strip()) for line in f), reverse=True))
    print(part1(containers))
    print(part2(containers))