-
Notifications
You must be signed in to change notification settings - Fork 0
/
part_a.py
executable file
·74 lines (62 loc) · 2.29 KB
/
part_a.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
#!/usr/bin/env python3
from collections import namedtuple
import utils
class Challenge(utils.BaseChallenge):
def solve(self, _input, debug=False):
"""
>>> Challenge().default_solve()
776203571
"""
encrypted = Decoder.read_encrypted_text(_input)
return Decoder(25).get_first_number_that_is_not_a_sum(encrypted)
class Decoder(namedtuple("Decoder", ("memory_size",))):
@classmethod
def read_encrypted_text(cls, encrypted_text):
"""
>>> Decoder.read_encrypted_text(
... "35\\n20\\n15\\n25\\n47\\n40\\n62\\n55\\n65\\n95")
(35, 20, 15, 25, 47, 40, 62, 55, 65, 95)
"""
return tuple(map(int, filter(None, encrypted_text.splitlines())))
def get_first_number_that_is_not_a_sum(self, encrypted):
"""
>>> encrypted_a = (
... 35, 20, 15, 25, 47, 40, 62, 55, 65, 95, 102, 117, 150, 182,
... 127, 219, 299, 277, 309, 576)
>>> Decoder(5).get_first_number_that_is_not_a_sum(encrypted_a)
127
"""
for position in range(self.memory_size, len(encrypted)):
found, number = self.check_position(encrypted, position)
if found:
return number
return None
def check_position(self, encrypted, position):
"""
>>> encrypted_a = (
... 35, 20, 15, 25, 47, 40, 62, 55, 65, 95, 102, 117, 150, 182,
... 127, 219, 299, 277, 309, 576)
>>> Decoder(5).check_position(encrypted_a, 5)
(False, None)
>>> Decoder(5).check_position(encrypted_a, 14)
(True, 127)
"""
last_n_numbers = encrypted[position - self.memory_size:position]
number = encrypted[position]
if not self.check_number(last_n_numbers, number):
return False, None
return True, number
def check_number(self, last_n_numbers, number):
"""
>>> Decoder(5).check_number((35, 20, 15, 25, 47), 40)
False
>>> Decoder(5).check_number((95, 102, 117, 150, 182), 127)
True
"""
return not any(
number == first + second
for first_index, first in enumerate(last_n_numbers)
for second in last_n_numbers[first_index + 1:]
)
Challenge.main()
challenge = Challenge()