Project Euler Problem #23 (non-abundant sums) [closed]
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
-1
down vote
favorite
Project Euler Problem 23
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.
I do not have a programming background. The code I have written is testing my patience and is not giving any solution. Kindly, provide the suggestions for the optimization.
array =
array1 =
for i in range(12, 28123):
add = 0
for j in range(1, i//2 + 1):
if i%j ==0:
add += j
if add > i:
array.append(i)
break
total_num = list(range(1,28124))
for k in range(len(array)):
for l in range(k, len(array)):
add = 0
add = array[k] + array[l]
if add not in array1 and add in total_num:
array1.append(add)
else:
continue
print(sum(total_num)-sum(array1))
python performance python-3.x programming-challenge time-limit-exceeded
closed as off-topic by Mast, Graipher, Vogel612â¦, Mathias Ettinger, t3chb0t Feb 9 at 10:47
This question appears to be off-topic. The users who voted to close gave this specific reason:
- "Questions containing broken code or asking for advice about code not yet written are off-topic, as the code is not ready for review. After the question has been edited to contain working code, we will consider reopening it." â Mast, Graipher, Vogel612, Mathias Ettinger, t3chb0t
add a comment |Â
up vote
-1
down vote
favorite
Project Euler Problem 23
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.
I do not have a programming background. The code I have written is testing my patience and is not giving any solution. Kindly, provide the suggestions for the optimization.
array =
array1 =
for i in range(12, 28123):
add = 0
for j in range(1, i//2 + 1):
if i%j ==0:
add += j
if add > i:
array.append(i)
break
total_num = list(range(1,28124))
for k in range(len(array)):
for l in range(k, len(array)):
add = 0
add = array[k] + array[l]
if add not in array1 and add in total_num:
array1.append(add)
else:
continue
print(sum(total_num)-sum(array1))
python performance python-3.x programming-challenge time-limit-exceeded
closed as off-topic by Mast, Graipher, Vogel612â¦, Mathias Ettinger, t3chb0t Feb 9 at 10:47
This question appears to be off-topic. The users who voted to close gave this specific reason:
- "Questions containing broken code or asking for advice about code not yet written are off-topic, as the code is not ready for review. After the question has been edited to contain working code, we will consider reopening it." â Mast, Graipher, Vogel612, Mathias Ettinger, t3chb0t
7
Please post a valid Python program. This fails because of indentation errors.
â GolfWolf
Feb 9 at 9:01
add a comment |Â
up vote
-1
down vote
favorite
up vote
-1
down vote
favorite
Project Euler Problem 23
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.
I do not have a programming background. The code I have written is testing my patience and is not giving any solution. Kindly, provide the suggestions for the optimization.
array =
array1 =
for i in range(12, 28123):
add = 0
for j in range(1, i//2 + 1):
if i%j ==0:
add += j
if add > i:
array.append(i)
break
total_num = list(range(1,28124))
for k in range(len(array)):
for l in range(k, len(array)):
add = 0
add = array[k] + array[l]
if add not in array1 and add in total_num:
array1.append(add)
else:
continue
print(sum(total_num)-sum(array1))
python performance python-3.x programming-challenge time-limit-exceeded
Project Euler Problem 23
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.
I do not have a programming background. The code I have written is testing my patience and is not giving any solution. Kindly, provide the suggestions for the optimization.
array =
array1 =
for i in range(12, 28123):
add = 0
for j in range(1, i//2 + 1):
if i%j ==0:
add += j
if add > i:
array.append(i)
break
total_num = list(range(1,28124))
for k in range(len(array)):
for l in range(k, len(array)):
add = 0
add = array[k] + array[l]
if add not in array1 and add in total_num:
array1.append(add)
else:
continue
print(sum(total_num)-sum(array1))
python performance python-3.x programming-challenge time-limit-exceeded
edited Aug 14 at 21:25
Deduplicator
9,8721844
9,8721844
asked Feb 9 at 8:44
R. Bajaj
61
61
closed as off-topic by Mast, Graipher, Vogel612â¦, Mathias Ettinger, t3chb0t Feb 9 at 10:47
This question appears to be off-topic. The users who voted to close gave this specific reason:
- "Questions containing broken code or asking for advice about code not yet written are off-topic, as the code is not ready for review. After the question has been edited to contain working code, we will consider reopening it." â Mast, Graipher, Vogel612, Mathias Ettinger, t3chb0t
closed as off-topic by Mast, Graipher, Vogel612â¦, Mathias Ettinger, t3chb0t Feb 9 at 10:47
This question appears to be off-topic. The users who voted to close gave this specific reason:
- "Questions containing broken code or asking for advice about code not yet written are off-topic, as the code is not ready for review. After the question has been edited to contain working code, we will consider reopening it." â Mast, Graipher, Vogel612, Mathias Ettinger, t3chb0t
7
Please post a valid Python program. This fails because of indentation errors.
â GolfWolf
Feb 9 at 9:01
add a comment |Â
7
Please post a valid Python program. This fails because of indentation errors.
â GolfWolf
Feb 9 at 9:01
7
7
Please post a valid Python program. This fails because of indentation errors.
â GolfWolf
Feb 9 at 9:01
Please post a valid Python program. This fails because of indentation errors.
â GolfWolf
Feb 9 at 9:01
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
I assume your original program is the following (as it is not properly indented in the question):
array =
array1 =
for i in range(12, 28123):
add = 0
for j in range(1, i//2 + 1):
if i%j ==0:
add += j
if add > i:
array.append(i)
break
total_num = list(range(1,28124))
for k in range(len(array)):
for l in range(k, len(array)):
add = 0
add = array[k] + array[l]
if add not in array1 and add in total_num:
array1.append(add)
else:
continue
print(sum(total_num)-sum(array1))
First of all, great job! I don't see any logical issues with your implementation.
Minor nitpick
Generally, it's best to avoid names like array
and array1
. This has nothing to do with performance, but helps a lot for program readability. Better names in this case for array
and array1
would be abundants
and abundant_sums
.
Performance
At a first glance, two big performance problems that can be easily addressed can be found on the line:
if add not in abundant_sums and add in total_num
These are two array lookups which take linear time (O(n)) and are executed for every possible pair of abundant numbers (which turns out to be a little over 48 million times!).
Let's takle both issues separately:
add not in abundants
- the way to remove this altogether is to makeabundant_sums
a set, rather than an array. This way, you can just sayabundant_sums.add(add)
without first checking if it's already there (OK, perhapsadd
should be called sum to avoid this :) )add in total_num
- this is basically just a range check. And actually, just an upper bound check, since the numbers you deal with could never yield a sum less than 24. So, instead ofadd in total_num
which traverses an array of 28+K items, you can just sayadd <= 28123
. That's it.
By just applying these two optimizations, I get a program that produces the correct result in a little over 30s:
abundants =
abundant_sums = set()
for i in range(12, 28123):
add = 0
for j in range(1, i//2 + 1):
if i%j ==0:
add += j
if add > i:
abundants.append(i)
break
print len(abundants)
total_num = list(range(1,28124))
for k in range(len(abundants)):
for l in range(k, len(abundants)):
add = 0
add = abundants[k] + abundants[l]
if add <= 28123:
abundant_sums.add(add)
print(sum(total_num)-sum(abundant_sums))
Another slight optimization that you could perform is to not compute the sum of total_num
, but just use the formula max * (max+1) / 2
. This is unlikely, however, to provide a major benefit in your case, since this calculation takes place only once. Anyway, I believe it's good to know this trick.
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
I assume your original program is the following (as it is not properly indented in the question):
array =
array1 =
for i in range(12, 28123):
add = 0
for j in range(1, i//2 + 1):
if i%j ==0:
add += j
if add > i:
array.append(i)
break
total_num = list(range(1,28124))
for k in range(len(array)):
for l in range(k, len(array)):
add = 0
add = array[k] + array[l]
if add not in array1 and add in total_num:
array1.append(add)
else:
continue
print(sum(total_num)-sum(array1))
First of all, great job! I don't see any logical issues with your implementation.
Minor nitpick
Generally, it's best to avoid names like array
and array1
. This has nothing to do with performance, but helps a lot for program readability. Better names in this case for array
and array1
would be abundants
and abundant_sums
.
Performance
At a first glance, two big performance problems that can be easily addressed can be found on the line:
if add not in abundant_sums and add in total_num
These are two array lookups which take linear time (O(n)) and are executed for every possible pair of abundant numbers (which turns out to be a little over 48 million times!).
Let's takle both issues separately:
add not in abundants
- the way to remove this altogether is to makeabundant_sums
a set, rather than an array. This way, you can just sayabundant_sums.add(add)
without first checking if it's already there (OK, perhapsadd
should be called sum to avoid this :) )add in total_num
- this is basically just a range check. And actually, just an upper bound check, since the numbers you deal with could never yield a sum less than 24. So, instead ofadd in total_num
which traverses an array of 28+K items, you can just sayadd <= 28123
. That's it.
By just applying these two optimizations, I get a program that produces the correct result in a little over 30s:
abundants =
abundant_sums = set()
for i in range(12, 28123):
add = 0
for j in range(1, i//2 + 1):
if i%j ==0:
add += j
if add > i:
abundants.append(i)
break
print len(abundants)
total_num = list(range(1,28124))
for k in range(len(abundants)):
for l in range(k, len(abundants)):
add = 0
add = abundants[k] + abundants[l]
if add <= 28123:
abundant_sums.add(add)
print(sum(total_num)-sum(abundant_sums))
Another slight optimization that you could perform is to not compute the sum of total_num
, but just use the formula max * (max+1) / 2
. This is unlikely, however, to provide a major benefit in your case, since this calculation takes place only once. Anyway, I believe it's good to know this trick.
add a comment |Â
up vote
2
down vote
accepted
I assume your original program is the following (as it is not properly indented in the question):
array =
array1 =
for i in range(12, 28123):
add = 0
for j in range(1, i//2 + 1):
if i%j ==0:
add += j
if add > i:
array.append(i)
break
total_num = list(range(1,28124))
for k in range(len(array)):
for l in range(k, len(array)):
add = 0
add = array[k] + array[l]
if add not in array1 and add in total_num:
array1.append(add)
else:
continue
print(sum(total_num)-sum(array1))
First of all, great job! I don't see any logical issues with your implementation.
Minor nitpick
Generally, it's best to avoid names like array
and array1
. This has nothing to do with performance, but helps a lot for program readability. Better names in this case for array
and array1
would be abundants
and abundant_sums
.
Performance
At a first glance, two big performance problems that can be easily addressed can be found on the line:
if add not in abundant_sums and add in total_num
These are two array lookups which take linear time (O(n)) and are executed for every possible pair of abundant numbers (which turns out to be a little over 48 million times!).
Let's takle both issues separately:
add not in abundants
- the way to remove this altogether is to makeabundant_sums
a set, rather than an array. This way, you can just sayabundant_sums.add(add)
without first checking if it's already there (OK, perhapsadd
should be called sum to avoid this :) )add in total_num
- this is basically just a range check. And actually, just an upper bound check, since the numbers you deal with could never yield a sum less than 24. So, instead ofadd in total_num
which traverses an array of 28+K items, you can just sayadd <= 28123
. That's it.
By just applying these two optimizations, I get a program that produces the correct result in a little over 30s:
abundants =
abundant_sums = set()
for i in range(12, 28123):
add = 0
for j in range(1, i//2 + 1):
if i%j ==0:
add += j
if add > i:
abundants.append(i)
break
print len(abundants)
total_num = list(range(1,28124))
for k in range(len(abundants)):
for l in range(k, len(abundants)):
add = 0
add = abundants[k] + abundants[l]
if add <= 28123:
abundant_sums.add(add)
print(sum(total_num)-sum(abundant_sums))
Another slight optimization that you could perform is to not compute the sum of total_num
, but just use the formula max * (max+1) / 2
. This is unlikely, however, to provide a major benefit in your case, since this calculation takes place only once. Anyway, I believe it's good to know this trick.
add a comment |Â
up vote
2
down vote
accepted
up vote
2
down vote
accepted
I assume your original program is the following (as it is not properly indented in the question):
array =
array1 =
for i in range(12, 28123):
add = 0
for j in range(1, i//2 + 1):
if i%j ==0:
add += j
if add > i:
array.append(i)
break
total_num = list(range(1,28124))
for k in range(len(array)):
for l in range(k, len(array)):
add = 0
add = array[k] + array[l]
if add not in array1 and add in total_num:
array1.append(add)
else:
continue
print(sum(total_num)-sum(array1))
First of all, great job! I don't see any logical issues with your implementation.
Minor nitpick
Generally, it's best to avoid names like array
and array1
. This has nothing to do with performance, but helps a lot for program readability. Better names in this case for array
and array1
would be abundants
and abundant_sums
.
Performance
At a first glance, two big performance problems that can be easily addressed can be found on the line:
if add not in abundant_sums and add in total_num
These are two array lookups which take linear time (O(n)) and are executed for every possible pair of abundant numbers (which turns out to be a little over 48 million times!).
Let's takle both issues separately:
add not in abundants
- the way to remove this altogether is to makeabundant_sums
a set, rather than an array. This way, you can just sayabundant_sums.add(add)
without first checking if it's already there (OK, perhapsadd
should be called sum to avoid this :) )add in total_num
- this is basically just a range check. And actually, just an upper bound check, since the numbers you deal with could never yield a sum less than 24. So, instead ofadd in total_num
which traverses an array of 28+K items, you can just sayadd <= 28123
. That's it.
By just applying these two optimizations, I get a program that produces the correct result in a little over 30s:
abundants =
abundant_sums = set()
for i in range(12, 28123):
add = 0
for j in range(1, i//2 + 1):
if i%j ==0:
add += j
if add > i:
abundants.append(i)
break
print len(abundants)
total_num = list(range(1,28124))
for k in range(len(abundants)):
for l in range(k, len(abundants)):
add = 0
add = abundants[k] + abundants[l]
if add <= 28123:
abundant_sums.add(add)
print(sum(total_num)-sum(abundant_sums))
Another slight optimization that you could perform is to not compute the sum of total_num
, but just use the formula max * (max+1) / 2
. This is unlikely, however, to provide a major benefit in your case, since this calculation takes place only once. Anyway, I believe it's good to know this trick.
I assume your original program is the following (as it is not properly indented in the question):
array =
array1 =
for i in range(12, 28123):
add = 0
for j in range(1, i//2 + 1):
if i%j ==0:
add += j
if add > i:
array.append(i)
break
total_num = list(range(1,28124))
for k in range(len(array)):
for l in range(k, len(array)):
add = 0
add = array[k] + array[l]
if add not in array1 and add in total_num:
array1.append(add)
else:
continue
print(sum(total_num)-sum(array1))
First of all, great job! I don't see any logical issues with your implementation.
Minor nitpick
Generally, it's best to avoid names like array
and array1
. This has nothing to do with performance, but helps a lot for program readability. Better names in this case for array
and array1
would be abundants
and abundant_sums
.
Performance
At a first glance, two big performance problems that can be easily addressed can be found on the line:
if add not in abundant_sums and add in total_num
These are two array lookups which take linear time (O(n)) and are executed for every possible pair of abundant numbers (which turns out to be a little over 48 million times!).
Let's takle both issues separately:
add not in abundants
- the way to remove this altogether is to makeabundant_sums
a set, rather than an array. This way, you can just sayabundant_sums.add(add)
without first checking if it's already there (OK, perhapsadd
should be called sum to avoid this :) )add in total_num
- this is basically just a range check. And actually, just an upper bound check, since the numbers you deal with could never yield a sum less than 24. So, instead ofadd in total_num
which traverses an array of 28+K items, you can just sayadd <= 28123
. That's it.
By just applying these two optimizations, I get a program that produces the correct result in a little over 30s:
abundants =
abundant_sums = set()
for i in range(12, 28123):
add = 0
for j in range(1, i//2 + 1):
if i%j ==0:
add += j
if add > i:
abundants.append(i)
break
print len(abundants)
total_num = list(range(1,28124))
for k in range(len(abundants)):
for l in range(k, len(abundants)):
add = 0
add = abundants[k] + abundants[l]
if add <= 28123:
abundant_sums.add(add)
print(sum(total_num)-sum(abundant_sums))
Another slight optimization that you could perform is to not compute the sum of total_num
, but just use the formula max * (max+1) / 2
. This is unlikely, however, to provide a major benefit in your case, since this calculation takes place only once. Anyway, I believe it's good to know this trick.
answered Feb 9 at 9:47
GolfWolf
1,3611818
1,3611818
add a comment |Â
add a comment |Â
7
Please post a valid Python program. This fails because of indentation errors.
â GolfWolf
Feb 9 at 9:01