user17253648
user17253648

Reputation:

Next perfect number function in Python

What I want to do: If the sum of dividors of a number is equal to the number, I want to print it. If it's not, I want to check if it is true for next numbers and print the smallest number which meets that condition. I've got this:

def next_perfect(n):
    sum=0
    for d in range(1, n):
        if n%d==0:
            sum=sum+d
    if sum==n:
        return n
    else:
        sum=0
        n=n+1
        for d in range(1, n):
            if n%d==0:
                sum=sum+d
            if sum==n:
                return n
            else:


print(next_perfect(25))
                

For example for:

print(next_perfect(25))

It should check 25, then check 26, 27, 28 and print 28. I don't have an idea how to end this. I want this loop to move back to the first "else" and start checking the conditions again for the next number, always if the number isn't good.

Upvotes: 1

Views: 264

Answers (2)

Alain T.
Alain T.

Reputation: 42133

You should place your logic in a while loop, increasing n at each iteration and only exiting the loop when n is a perfect number:

def isPerfect(n):
    return 2*n == sum(sum({d,n//d}) for d in range(1,int(n**0.5)+1) if n%d==0)

def nextPerfect(n):
    n += 1
    while not isPerfect(n):
        n += 1
    return n

The problem with that solution is the time it will take to reach even the 5th perfect number (you won't want to wait that long). At that point you might as well hard code the first few perfect numbers in a list:

def nextPerfect(n):
    firstPerfects = [6, 28, 496, 8128, 33550336, 8589869056, 
                     137438691328, 2305843008139952128, 
                     2658455991569831744654692615953842176,              
                     191561942608236107294793378084303638130997321548169216]
    return next(p for p in firstPerfects if p>n)

Upvotes: 0

not_speshal
not_speshal

Reputation: 23156

Use a while loop and return when you find the required number:

def next_perfect(n):
    while True:
        total=sum(d for d in range(1, n) if n%d==0)
        if total==n:
            return n
        n=n+1

>>> next_perfect(25)
28

Or with recursion:

def next_perfect(n):
    total=sum(d for d in range(1, n) if n%d==0)
    if total==n:
        return n
    else:
        return next_perfect(n+1)

Upvotes: 1

Related Questions