73 lines
2.6 KiB
Python
73 lines
2.6 KiB
Python
|
input_file = "input.txt"
|
||
|
|
||
|
|
||
|
# Sum each pair of number available, return True if target can be reached
|
||
|
def is_sum_of_two(available_numbers, target):
|
||
|
for index in range(len(available_numbers)):
|
||
|
for number in available_numbers[index+1:]:
|
||
|
if available_numbers[index]+number == target:
|
||
|
return True
|
||
|
return False
|
||
|
|
||
|
|
||
|
def find_invalid_digit():
|
||
|
sliding_last_digits = []
|
||
|
|
||
|
with open(input_file) as encoded_digits:
|
||
|
line = encoded_digits.readline()
|
||
|
|
||
|
# Read the header data
|
||
|
while len(sliding_last_digits) < 25:
|
||
|
sliding_last_digits.append(int(line))
|
||
|
line = encoded_digits.readline()
|
||
|
|
||
|
while line and line != "\n":
|
||
|
if not is_sum_of_two(sliding_last_digits, int(line)):
|
||
|
print(f"{int(line)} is not the sum of two of the 25 preceding numbers.")
|
||
|
return int(line)
|
||
|
|
||
|
sliding_last_digits.pop(0)
|
||
|
sliding_last_digits.append(int(line))
|
||
|
|
||
|
line = encoded_digits.readline()
|
||
|
|
||
|
|
||
|
def find_vulnerability(invalid_digit=0):
|
||
|
"""
|
||
|
This works by adding every contiguous number until it goes over the target number.
|
||
|
When it goes over, it drops the first number of the contiguous series until it can add the new one.
|
||
|
Thus, the contiguous slice of the main list of number only shrinks on one side and only expands on the other.
|
||
|
"""
|
||
|
currently_summed = []
|
||
|
current_sum = 0
|
||
|
|
||
|
with open(input_file) as encoded_digits:
|
||
|
line = encoded_digits.readline()
|
||
|
next_number = int(line)
|
||
|
|
||
|
while line and line != "\n":
|
||
|
if current_sum == invalid_digit:
|
||
|
print(f"Found contiguous sum : {currently_summed}\n"
|
||
|
f"The vulnerability is : {min(currently_summed)}+{max(currently_summed)} = "
|
||
|
f"{min(currently_summed) + max(currently_summed)}")
|
||
|
break
|
||
|
|
||
|
elif current_sum + next_number < invalid_digit:
|
||
|
currently_summed.append(next_number)
|
||
|
current_sum += next_number
|
||
|
|
||
|
elif current_sum + next_number > invalid_digit:
|
||
|
# Would continue indefinitely if nex_number > invalid_digit. Should not happen.
|
||
|
while current_sum + next_number > invalid_digit:
|
||
|
# Pop the first numbers of the list until we can add the new one
|
||
|
current_sum -= currently_summed.pop(0)
|
||
|
|
||
|
currently_summed.append(next_number)
|
||
|
current_sum += next_number
|
||
|
|
||
|
line = encoded_digits.readline()
|
||
|
next_number = int(line)
|
||
|
|
||
|
|
||
|
find_vulnerability(find_invalid_digit())
|