-
Notifications
You must be signed in to change notification settings - Fork 0
/
day03.py
93 lines (77 loc) · 2.17 KB
/
day03.py
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
from itertools import count
from typing import Tuple, Iterable, Generator, Hashable, TypeVar, Any
from sys import argv
example_rucksacks = [
"vJrwpWtwJgWrhcsFMMfFFhFp",
"jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL",
"PmmdzqPrVvPwwTWBwg",
"wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn",
"ttgJtRGJQctTZtZT",
"CrZsJsPPZsGzwwsLwLmpwMDw",
]
def priority(item_type: str) -> int:
"""
>>> priority("a")
1
>>> priority("z")
26
>>> priority("A")
27
"""
code = ord(item_type)
if ord('a') <= code and code <= ord('z'):
return code - ord('a') + 1
elif ord('A') <= code and code <= ord('Z'):
return code - ord('A') + 27
else:
raise Exception(f'{item_type} is not a valid item type')
def even(n: int) -> bool:
"""
>>> even(2)
True
"""
return n % 2 == 0
def compartments(rucksack: str) -> Tuple[str, str]:
"""
>>> compartments('abcd')
('ab', 'cd')
"""
if not even(len(rucksack)):
raise Exception(f'rucksack cannot have uneven length')
cutoff = len(rucksack) // 2
return rucksack[:cutoff], rucksack[cutoff:]
def problem1(rucksacks: Iterable[str]) -> int:
return sum(
priority(next(iter(set(first_comp).intersection(set(second_comp)))))
for first_comp, second_comp in map(compartments, rucksacks)
)
S = TypeVar('S')
def groups(xs: Iterable[S], size: int) -> Generator[S, None, None]:
"""
>>> list(groups([1,2,3,4], 2))
[(1, 2), (3, 4)]
"""
yield from (
tuple(xs[offset:offset + size])
for offset in range(0, len(xs), size)
)
T = TypeVar('T', bound=Hashable)
def intersection(*sets: Iterable[Iterable[T]]) -> set[T]:
"""
>>> intersection('abc', 'cde')
{'c'}
"""
state = set(sets[0])
for s in sets[1:]:
state.intersection_update(s)
return state
def problem2(rucksacks: Iterable[str]) -> int:
return sum(
priority(next(iter(intersection(*group))))
for group in groups(rucksacks, 3)
)
if __name__ == '__main__':
with open(argv[1]) as f:
rucksacks = list(line.rstrip() for line in f.readlines())
print(problem1(rucksacks))
print(problem2(rucksacks))