Solve problem 103 bruteforce in Python
This commit is contained in:
83
python/e103.py
Normal file
83
python/e103.py
Normal file
@@ -0,0 +1,83 @@
|
||||
|
||||
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 no 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 next_set_heuristic(xs):
|
||||
""" Calculate the estimated next optimum based on the formul given in the
|
||||
question. """
|
||||
b = xs[(len(xs) - 1) // 2]
|
||||
next_set = [b]
|
||||
for a in xs:
|
||||
next_set.append(a + b)
|
||||
return next_set
|
||||
|
||||
|
||||
def euler_103():
|
||||
e_max = 50
|
||||
min_set = None
|
||||
for a in range(1, e_max):
|
||||
for b in range(a + 1, e_max):
|
||||
for c in range(b + 1, e_max):
|
||||
for d in range(c + 1, e_max):
|
||||
for e in range(d + 1, e_max):
|
||||
for f in range(e + 1, e_max):
|
||||
for g in range(e + 1, e_max):
|
||||
s = [a, b, c, d, e, f, g,]
|
||||
if is_special_sum_set(s):
|
||||
s_sum = sum(s)
|
||||
if min_set is None or s_sum < sum(min_set):
|
||||
min_set = s
|
||||
return int("".join(map(str, min_set)))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
solution = euler_103()
|
||||
print("e103.py: " + str(solution))
|
||||
assert(solution == 20313839404245)
|
||||
|
||||
Reference in New Issue
Block a user