-1

I am making an algorithm with python to find perfect numbers up to 100000000000000. I have created some code for this that should do it, and it does not throw up any errors, but the code just outputted nothing and is running continuously. I have checked, and the first perfect number is six, so why is my program taking so long to get there?

Here is my code:

    number = 1
    divisor = 2
    factors = 1

    if number < 100000000000000:

        while True:
            number2 = number/divisor
            if isinstance(number2, int):
                factors = factors + divisor + number2
                divisor = divisor + 1

            if divisor == number:
                if factors  == number:
                    print(number)
                    number = number + 1

                break
AtomProgrammer
  • 245
  • 3
  • 13
  • 1
    `while True:` _never_ breaks out. You presumably wanted your `if` to be inside the `while` loop, but I'm still not sure the code logic holds for what you're trying to accomplish. – roganjosh Jun 06 '19 at 20:30
  • `while True` is always very dangerous. The likely culprit here is that you're not reaching the `break` statement - I would advise instead doing `for number in range(100000000000000)`, which will just iterate through the numbers one by one – Green Cloak Guy Jun 06 '19 at 20:31
  • @GreenCloakGuy they cannot ever reach the `break` because its indentation is outside of the `while` loop. I'm not sure I understand why a `while True` loop is always "very dangerous" - it is no different than `while some_condition` and relying on that condition to switch – roganjosh Jun 06 '19 at 20:35
  • @roganjosh I'm being generous and assuming the indentation is posted wrong, as it so often is in amateur StackOverflow posts. That would also be the issue, though – Green Cloak Guy Jun 06 '19 at 20:36
  • Even if indentation is not at fault, the if number < 10000000, is before the while loop, so it is tested once. With number = 1, all the if conditions are false except number < 100000000 –  Jun 06 '19 at 21:20
  • 1
    See this lovely [debug](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) blog for help. If nothing else, a simple `print` statement to trace values would immediately show the problem; follow up with more to find the rationale. Just staring at your code doesn't reveal the problem as often as we expect. :-) – Prune Jun 06 '19 at 22:25

2 Answers2

0

In both of these examples, I used the variable "j" for the target number.

This was my first thought, but please do not use it on anything bigger than 10000:

print([i for i in range(1,j+1) if i == sum(k for k in range(1,i//2+1) if i%k == 0)])

Since perfect numbers cannot be prime, I decided to alter a sieve to reduce the amount of numbers to calculate. The sieve can be found here Sieve of Eratosthenes. There is a good explanation there and on the wiki about the sieve.

def SieveOfEratosthenes(n):
    prime = [True for i in range(n+1)] 
    p = 2
    while (p * p <= n):
        if (prime[p] == True): 
            for i in range(p * 2, n+1, p): 
                prime[i] = False
        p += 1
    for p in range(2, n):
        if not prime[p]:
            #this is my change
            if p == sum(k for k in range(1,p//2+1) if p%k == 0):
                yield p
a = SieveOfEratosthenes(j)
b = next(a)
print(b)
try:
    while b < j:
        b = next(a)
        print(b)
except StopIteration:
    print("Done")

These work in theory, but I can't get it to work in a "reasonable" amount of time.

Hopefully these will help until someone can post a more efficient solution.

0

Even if you fix your code, it's the wrong approach for looking for perfect numbers - you're not likely to find more than the first four, and certainly not perfect numbers up to 100,000,000,000,000.

A better approach would be to search for Mersenne primes using a Lucas-Lehmer primality test and when you find one, compute its companion perfect number. This doesn't take much code and will easily eclipse your current approach.

cdlane
  • 40,441
  • 5
  • 32
  • 81