Solve problem 105 in Python way quicker than expected
This commit is contained in:
74
python/e105.py
Normal file
74
python/e105.py
Normal file
@@ -0,0 +1,74 @@
|
||||
|
||||
def build_sets(sets, numbers):
|
||||
""" Sets is a list of two tuples. Each field represents the sum of the two
|
||||
sets. For each new number, we can add the number to set one, add the
|
||||
number to set two, or don't add the number to any sets. If there are no
|
||||
more numbers we return the list so that we can check if there are tuples
|
||||
that have the same sum. """
|
||||
if not numbers:
|
||||
return sets
|
||||
current_number, numbers = numbers[0], numbers[1:]
|
||||
new_sets = []
|
||||
for t in sets:
|
||||
new_sets.append(t)
|
||||
new_sets.append((t[0] + current_number, t[1]))
|
||||
new_sets.append((t[0], t[1] + current_number))
|
||||
return build_sets(new_sets, numbers)
|
||||
|
||||
|
||||
def is_condition_one_met(s):
|
||||
tuples = build_sets([(0, 0)], s)
|
||||
for a, b in tuples:
|
||||
if a != 0 and b != 0 and a == b:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def is_condition_two_met(s):
|
||||
""" The second condition says that if |B| > |C| then sum(B) > sum(C). Since
|
||||
each line is sorted we take the two smallest integers and compare it to the
|
||||
biggest. Then we take the three smallest integers and compare it to the two
|
||||
biggest, and so on. Comparing the smallest with the biggest integers is the
|
||||
worst case and if there is violation of the condition it will be met for
|
||||
all other subset pairs. """
|
||||
half_len = (len(s) - 1) // 2
|
||||
for i in range(1, half_len + 1):
|
||||
if not sum(s[:i + 1]) > sum(s[-i:]):
|
||||
# print(f"{s[:i + 1]=} < {s[-i:]=}")
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def is_special_sum_set(s):
|
||||
""" Check for the two conditions and return True if they are both met. """
|
||||
if not is_condition_two_met(s):
|
||||
return False
|
||||
if not is_condition_one_met(s):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def load_sets():
|
||||
""" Parse sets from file into a list of lists. Each line contains a list of
|
||||
comma separated integers. We sort the integers in each line. """
|
||||
def line_to_set(line):
|
||||
return sorted(map(int, line.strip().split(",")))
|
||||
|
||||
with open("../txt/e105.txt") as f:
|
||||
return list(map(line_to_set, f))
|
||||
|
||||
|
||||
def euler_105():
|
||||
xs = load_sets()
|
||||
s = 0
|
||||
for i, x in enumerate(xs):
|
||||
if is_special_sum_set(x):
|
||||
s += sum(x)
|
||||
return s
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
solution = euler_105()
|
||||
print("e105.py: " + str(solution))
|
||||
assert(solution == 73702)
|
||||
|
||||
Reference in New Issue
Block a user