Reputation:
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
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
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