Problem 23: Non-abundant Sums
A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.
A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.
As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.
Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.
def divisors(n):
"""Returns proper divisors of n"""
lst = [1]
for i in range(2, int(n**0.5)+1):
if n % i == 0:
lst.append(i)
lst.append(n//i)
return list(set(lst))
# creating a list of distances between abundant numbers. this will be used to find sums.
distances = []
last = 0
# numbers past 28123-12 should never be able to add to a number below 28123
for i in range(1, 28123-12+1):
if i < sum(divisors(i)):
distances.append(i - last)
last = i
# remove 12 from distances, it isn't actually useful going forward
del distances[0]
# to find list of sums of two abundant nums, look through distances by index i
#
# to list of sums, append:
# A. distance at i added to each value in the list of sums APPENDED in step i-1
# B. distance at i added to last value added in substep A
#
# basis list of sums is [24]
#
# this gives a sequence like: (where bracketed items are what was appended in previous step)
#
# 0. [24]
# 1. 24, [30, 36]
# 2. 24, 30, 36, [32, 38, 40]
# 3. 24, 30, 36, 32, 38, 40, [36, 42, 44, 48]
# 4. 24, 30, 36, 32, 38, 40, 36, 42, 44, 48, [42, 48, 50, 54, 60]
#
# in step 0, distances[0] = 6 and basis sums previously appended = [24]
# so to create sums list for next step (1), append:
# A. 24 + 6 = 30
# B. 30 + 6 = 36
#
# in step 1, distances[1] = 2, sums previously appended = [30, 36]
# append:
# 30 + 2 = 32
# 36 + 2 = 38
# 38 + 2 = 40
sums = [24]
for i in range(len(distances)):
for j in sums[-i-1:]:
sums.append(distances[i] + j)
sums.append(distances[i] + sums[-1])
# sort, remove duplicates
st = sorted(list(set(sums)))
# tally all numbers in range that are not abundant sums to get the answer
t = 0
for i in range(1, 28124):
if i not in st:
t += i
print(f"Sum of all non-abundant sums: {t}")
# extra:
# unlike the analysis described in the prompt, using this method we are able to
# find the greatest number that cannot be expressed as the sum of two abundant numbers.
# (assuming that all integers greater than 28123 can indeed be written as sums like the question states.)
for i in range(st.index(28124), 0, -1):
if st[i-1] != st[i] - 1:
print(f"Greatest number with no abundant sum: {st[i] - 1}")
break
# write to file to analyze output, entirely optional but interesting
with open('sums.txt', 'w') as f:
for i in sorted(list(set(sums))):
f.write(str(i) + '\n')
Click to reveal output
Sum of all non-abundant sums: 4179871
Greatest number with no abundant sum: 20161
File output: sums.txt