p = []
for x in range(1, 50000000):
count = 0
for y in range(1, x // 2 + 1):
if (x % y == 0):
count += y
if (count == x):
p.append(x)
This is my code to try and find all the perfect numbers that originate between 1 and 50000000. It works fine for the first 3 numbers, they are between 1 and 10000. But as it progresses it becomes extremely slow. Like maybe going through 1000 numbers every 10 seconds. Then eventually going through 10 numbers every 5 seconds.
Now is there anyway I could make this faster? I tried including some smaller things, like diving x by 2 to make sure we don't go over half (not going to be a multiple of x)
You can do a lot better. Consider the following:
1) Think of the factorization of 36 for example: 1x36, 2x18, 3x12, 4x9, 6x6. And that's it. Going further doesn't add anything new. The next factorization would be 9x4 but we already know that (4x9). This advantage gets progressively larger (compare the root of the last number you have to check against its half)
2) There are no odd perfect numbers. This is actually a conjecture (not proven yet) but they tried everything below 10^300 and didn't find any. So there are definately exactly none < 50000000. That means you can skip half the terms.
This should be a lot faster but there are definately more things one can do.
Here's a solution using some precomputed values of Mersenne Primes:
Output:
As has already been mentioned, no odd perfect numbers have been found. And according to the Wikipedia article on perfect numbers, if any odd perfect numbers exist they must be greater than 101500. Clearly, looking for odd perfect numbers takes sophisticated methods &/or a lot of time. :)
As stated on Wikipedia, Euclid proved that even perfect numbers can be produced from Mersenne primes, and Euler proved that, conversely, all even perfect numbers have that form.
So we can produce a list of even perfect numbers by generating Mersenne primes. And we can (relatively) quickly test if a number is a Mersenne prime via the Lucas-Lehmer test.
Here's a short program that does just that. The
primes
function used here was written by Robert William Hanks, the rest of the code was just written by me a few minutes ago. :)output
That output was produced in 4.5 seconds on a 2GHz 32 bit machine. You can easily produce larger Mersenne primes and perfect numbers, but don't expect it to be fast.