1

I have a code that reads 2 integers, m and n, and prints all the perfect numbers between m and n (inclusive m and n). If I input 2 and 7, it should give me 6. But it gives me 13. What went wrong?

m=int(input())
n=int(input())

myList=[]

for i in range(m,n+1):
    for j in range(1,i):
        if i%j==0:
            myList.append(j)

sum=0
for i in range(0,len(myList)):
    sum=sum+myList[i]
    for j in range(m,n+1):
        if sum==j:
            sum=j

print(sum)
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
Yolanda Hui
  • 97
  • 1
  • 1
  • 8
  • 3
    1. Don't use the name `sum` for a variable. It hides the builtin `sum` function. 2. `if sum == j: sum = j` What is the purpose of this `if`? it makes no sense – DeepSpace Oct 02 '18 at 14:42
  • it stores j in sum, so the print function can be moved outside the for loops to avoid being printed multiple times – Yolanda Hui Oct 02 '18 at 14:43
  • @mkrieger1 A perfect number is the sum of it's proper divisors, so 1 is included as a divisor, but the number itself isn't. Eg, 6, 28. – PM 2Ring Oct 02 '18 at 14:45
  • 1
    @YolandaHui That entire nested loop can be replaced with a single line, `print(sum(myList))` (If you don't do `sum = 0` of course) – DeepSpace Oct 02 '18 at 14:45
  • numbers in myList repeats, the fastest way to correct this is by using `set` and `list` - `myList = list(set(myList))` – Shan Oct 02 '18 at 14:47
  • Apart from the problem DeepSpace mentioned, your algorithm isn't going to work. Your upper loops mix together all the divisors of all the numbers in the m to n range. – PM 2Ring Oct 02 '18 at 14:48
  • @DeepSpace: I would first try to answer what the OP's question title say ;) – Sheldore Oct 02 '18 at 14:48
  • @Shan not really, it's only a coincidence that it works in this case. For the next number it will find 40 instead of 28. – DeepSpace Oct 02 '18 at 14:49
  • have you tried different values, was the results always sum = sum + sum+1? – Pizza lord - on strike Oct 02 '18 at 14:49
  • 2
    https://stackoverflow.com/q/52608553/6360875 – Tanmay jain Oct 02 '18 at 14:52
  • @DeepSpace ok have to admit I didn't test this too much, hence only commenting quickly. – Shan Oct 02 '18 at 14:56
  • BTW, brute force searching for perfect numbers becomes impractical after the first 5 or 6. If you want a fast way to find even perfect numbers in Python, see my code [here](https://stackoverflow.com/a/40631767/4014959). It won't find odd perfect numbers, but they probably don't exist, and if any do  they must be greater than 10**1500. – PM 2Ring Oct 02 '18 at 15:02

4 Answers4

2

You're making this more complicated than it needs to be. You need one nested loop to solve this. Iterate through every number in your range, set a value x equal to 0 and every time you find a number that divides evenly, add it to x. If at the end of your inner loop, x == i, then you have a perfect number and print it out. If you need it in a list, append it to your list. You're trying to save all the intermediate numbers, just save the result if you find it.

for i in range(m,n+1):
    x = 0
    for j in range(1,i):
        if i % j == 0:
            x += j
    if i == x:
        print(i)
0

What you want to do is something like this.

Add all the divisors of a number expect the number itself into a list then check if the sum of that list is equal to the number . If it is equal print the number else take the next number

m=int(input())
n=int(input())


for i in range(m,n+1):

    myList=[]
    for j in range(1,i):
        if i%j==0:
            myList.append(j)
    if sum(myList)==i:
        print(i)

Input

2
7

Output

6
Albin Paul
  • 3,330
  • 2
  • 14
  • 30
0

you should iterate to n/2, since any "number" cant be divisible by any number which is greater than half of "number".

for i in range(m, n+1):
    _sum = 0
    for j in range(1, int(i/2)+1):
        if i%j==0:
            _sum += j
    if _sum==i:
       print(i)
GraphicalDot
  • 2,644
  • 2
  • 28
  • 43
  • True, and that can be optimized further, by searching for pairs of factors, and stopping at the square root. But why bother saving them to a list? Just add them up as you find them. – PM 2Ring Oct 02 '18 at 15:09
  • Let me check which operation is cheaper, append or sum. – GraphicalDot Oct 02 '18 at 15:12
  • Even if you use a list you still have to do the addition eventually. The addition itself is pretty fast, creating a new Python integer object eventually gets slow when the number has thousands of digits. But that's not an issue here. – PM 2Ring Oct 02 '18 at 15:19
  • See how long it takes to verify that 8589869056 is perfect. ;) – PM 2Ring Oct 02 '18 at 15:20
0
m=int(input())
n=int(input())

'''
mylist =[]  instead of using myList to keep track of factors 
just use sum_of_factors_of_i variable and keep adding newly found factors to 
it by doing so you will not need to loop over myList to get sum.
'''
for i in range(m,n+1):
    sum_of_factors_of_i = 0
    for j in range(1,i):
        if i%j==0:
            sum_of_factors_of_i += j

    if sum_of_factors_of_i == i:
        print(i)

'''        
input 
2
7

output
6
----------------------------------
input
2
30

output
6
28
'''
Tanmay jain
  • 814
  • 6
  • 11