2020-12-04 23:10:35 +01:00
|
|
|
target = 2020
|
2020-12-05 00:04:09 +01:00
|
|
|
input_file = "input.txt"
|
|
|
|
|
2020-12-04 23:10:35 +01:00
|
|
|
|
|
|
|
def find_sum_of_two():
|
2020-12-05 00:04:09 +01:00
|
|
|
"""
|
|
|
|
Find two numbers from a list that add to a target.
|
|
|
|
This is done by separating the numbers in a smaller than half and bigger than half of the target,
|
|
|
|
and trying to find a match that would complement the sum, rather than adding everything together.
|
|
|
|
:return: None
|
|
|
|
"""
|
2020-12-04 23:10:35 +01:00
|
|
|
large_n = []
|
|
|
|
small_n = []
|
|
|
|
|
|
|
|
with open(input_file) as file:
|
|
|
|
line = file.readline()
|
|
|
|
while line and line != "\n":
|
|
|
|
halftarget_count = 0
|
|
|
|
|
|
|
|
number = int(line)
|
|
|
|
if number > target/2:
|
|
|
|
large_n.append(number)
|
|
|
|
elif number == target/2:
|
2020-12-05 00:04:09 +01:00
|
|
|
# Used for "early" exit if we find twice the half
|
2020-12-04 23:10:35 +01:00
|
|
|
halftarget_count += 1
|
|
|
|
else:
|
|
|
|
small_n.append(number)
|
|
|
|
|
|
|
|
if halftarget_count == 2:
|
|
|
|
print(f"Found a sum : {target/2}*2 = {target}\nAnswer is {(target/2)**2}")
|
|
|
|
break
|
|
|
|
|
|
|
|
line = file.readline()
|
|
|
|
|
2020-12-05 00:04:09 +01:00
|
|
|
# This was chosen in this order because of input I got : mainly large numbers
|
2020-12-04 23:10:35 +01:00
|
|
|
for big_one in large_n:
|
|
|
|
complement = target-big_one
|
|
|
|
if complement in small_n:
|
|
|
|
print(f"Found a sum : {big_one}+{complement} = {target}\nAnswer is {big_one*complement}")
|
|
|
|
return
|
|
|
|
|
|
|
|
print("No sum found that can reach {target}")
|
|
|
|
|
2020-12-05 00:04:09 +01:00
|
|
|
|
2020-12-04 23:10:35 +01:00
|
|
|
def sum_search(target_sum, inputs):
|
2020-12-05 00:04:09 +01:00
|
|
|
"""
|
|
|
|
Basically the same as above but for an arbitrary target and list of numbers.
|
|
|
|
:param target_sum: Sum that we are looking numbers to reach
|
|
|
|
:param inputs: List of numbers to search for a pair adding to target_sum
|
|
|
|
:return: The pair if found, False otherwise
|
|
|
|
"""
|
2020-12-04 23:10:35 +01:00
|
|
|
lower = []
|
|
|
|
upper = []
|
|
|
|
|
|
|
|
for num in inputs:
|
|
|
|
if num < target_sum/2:
|
|
|
|
lower.append(num)
|
|
|
|
else:
|
|
|
|
upper.append(num)
|
|
|
|
|
2020-12-05 00:04:09 +01:00
|
|
|
# As those list might be of a different repartition, search the smaller one while iterating on the larger one
|
2020-12-04 23:10:35 +01:00
|
|
|
search_list = lower if len(lower) < len(upper) else upper
|
|
|
|
iter_list = upper if len(lower) < len(upper) else lower
|
|
|
|
|
|
|
|
for num in iter_list:
|
|
|
|
if target_sum - num in search_list:
|
|
|
|
return num, target_sum-num
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
def find_sum_of_three():
|
2020-12-05 00:04:09 +01:00
|
|
|
"""
|
|
|
|
Find a triplet of number that reach a target when added together. This time, constructing a list by subtracting each
|
|
|
|
number to the target, and using this list to check if the we can find two other numbers that add up to it.
|
|
|
|
To put it another way, instead of searching for a,b and c in a+b+c = t, search for a,b in a+b = t-c for every c.
|
|
|
|
:return: None
|
|
|
|
"""
|
2020-12-04 23:10:35 +01:00
|
|
|
data = []
|
|
|
|
subtracted_to_target = []
|
|
|
|
with open(input_file) as file:
|
|
|
|
line = file.readline()
|
|
|
|
while line and line != "\n":
|
|
|
|
data.append(int(line))
|
2020-12-05 00:04:09 +01:00
|
|
|
subtracted_to_target.append((target-data[-1], data[-1]))
|
2020-12-04 23:10:35 +01:00
|
|
|
|
|
|
|
line = file.readline()
|
|
|
|
|
2020-12-05 00:04:09 +01:00
|
|
|
# Honestly not sure if it helps
|
2020-12-04 23:10:35 +01:00
|
|
|
data.sort()
|
|
|
|
|
|
|
|
for sub_target in subtracted_to_target:
|
2020-12-05 00:04:09 +01:00
|
|
|
result = sum_search(sub_target[0], data)
|
2020-12-04 23:10:35 +01:00
|
|
|
if result:
|
|
|
|
print(f"Sum found : {result[0]}+{result[1]}+{sub_target[1]} = {target}\nResult is {result[0]*result[1]*sub_target[1]}")
|
|
|
|
return
|
|
|
|
|
|
|
|
print("No sum found")
|