简体   繁体   中英

Project Euler #23 Optimization

Non-abundant sums

Problem 23

A number n is called abundant if the sum of its proper divisors exceeds n. Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.

I have tried several things and optimized my code as much as I could with my limited knowledge of coding. A few days ago I started learning how to code, and I found this page, (project euler), I deviated a little from learning and just started to code to try and solve the problems. So far I've managed to solve most of the easiest problems without taking a long time, but this one is taking too long in comparison. Sorry if my code isn't understandable.

sum_abundant = []
for i in abundant:
    for n in abundant:
        c = i + n
        if n > i:
            break
        if c < 28123:
            if c not in sum_abundant:  # if the number has already been removed, it won't remove it again.
                sum_abundant.append(c)

("abundant" is a list with all the abundant numbers.) It isn't the whole code, just the part where I believe it takes most of the time.

One approach that you could take is to decompose the problem into intermediate steps:

  • Determine the proper divisors of all numbers up to 28123
  • Select the numbers that are "abundant" using the lists of divisors
  • Find all pairs of abundant numbers and flag their sums
  • Select the numbers that were not flagged by the previous steps (those will be the numbers that cannot be expressed as the sum of two abundants)
  • Compute the sum of this result

here's an example:

# Create a list of proper divisora for all numbers up to 28123...

properDivs     = [ [] for _ in range(28124) ] 
for n in range(1,28124):
    for i in range(2*n,28124,n):
        properDivs[i].append(n)

# Select the numbers that are abundant (sum of divisors > number itself)...

abundants = [n for n,divs in enumerate(properDivs) if sum(divs)>n]

# Find all pairs of abundant numbers and flag their sums

from itertools import combinations_with_replacement
sumOf2Abundants = [False for _ in range(28124)]
for a,b in combinations_with_replacement(abundants,2):
    if a+b<len(sumOf2Abundants):
        sumOf2Abundants[a+b] = True

# Select numbers that were not flagged...

result = [n for n,isSumOf2 in enumerate(sumOf2Abundants) if not isSumOf2]

# compute and print the sum of the above result

print(sum(result))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM