-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathday02_checksum.py
98 lines (75 loc) · 2.39 KB
/
day02_checksum.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
94
95
96
97
98
from collections import Counter
from typing import Generator, List, Optional
def load_input(filename: str) -> List[str]:
with open(filename, "r") as f:
lines = f.readlines()
return [line.strip() for line in lines]
def calculate_checksum(boxes: List[str]) -> int:
appears_twice = 0
appears_thrice = 0
for box in boxes:
counts = Counter(box)
values = set(counts.values())
if 2 in values:
appears_twice += 1
if 3 in values:
appears_thrice += 1
return appears_twice * appears_thrice
test_input_part_one = """abcdef
bababc
abbcde
abcccd
aabcdd
abcdee
ababab"""
assert calculate_checksum(test_input_part_one.split()) == 12
def find_similar_boxes(boxes: List[str]) -> Generator:
box_char_count = [Counter(box) for box in boxes]
for i in range(len(box_char_count)):
for j in range(i, len(box_char_count)):
box1 = box_char_count[i]
box2 = box_char_count[j]
diff = box1 - box2
if len(diff) == 1:
yield boxes[i], boxes[j]
def find_prototype_box_common_letters(boxes: List[str]) -> Optional[str]:
for box1, box2 in find_similar_boxes(boxes):
diff = 0
same = ""
for letter1, letter2 in zip(list(box1), list(box2)):
if letter1 != letter2:
diff += 1
else:
same += letter1
if diff == 1:
return same
return None
test_input_part_two = """abcde
fghij
klmno
pqrst
fguij
axcye
wvxyz"""
assert find_prototype_box_common_letters(test_input_part_two.split()) == "fgij"
def find_prototype_box_single_pass(boxes: List[str]) -> Optional[str]:
for i in range(len(boxes)):
for j in range(i, len(boxes)):
diff = 0
same = ""
for letter1, letter2 in zip(list(boxes[i]), list(boxes[j])):
if letter1 != letter2:
diff += 1
if diff > 1:
break
else:
same += letter1
if diff == 1:
return same
return None
assert find_prototype_box_single_pass(test_input_part_two.split()) == "fgij"
if __name__ == "__main__":
boxes = load_input("data/day02_input.txt")
print(calculate_checksum(boxes))
print(find_prototype_box_common_letters(boxes))
print(find_prototype_box_single_pass(boxes))