0

I am trying to find the perfect number by find out all their divisors. If their sum is equal to the number, then print out the the number. But apparently it's not working.

import acm.program.*;

public class PerfectNumber extends ConsoleProgram{
    public void run() {
        for (int n = 1; n < 9999; n++) {                                                                    
            for (int d = 2; d < n - 1; d++) {
                //d is the potential divisor of n, ranging from 2 to n-1,// 
                //not including 1 and n because they must be the divisors.//
            if (isPerfectNumber(n,d)) 
                print(n );
        }
    }
}

//method that determines if n is perfect number.//
    private boolean isPerfectNumber(int n, int d) {
         while (n % d == 0) {
         int spd = 1;
         spd += d;
         if (spd == n) {
         return true;
         } else {   
          return false;
             }
        }
    }
}
false
  • 10,264
  • 13
  • 101
  • 209
JackDee
  • 1
  • 1
  • 4
  • What's your problem with this? – Luiggi Mendoza Nov 08 '13 at 15:43
  • See http://en.wikipedia.org/wiki/Perfect_number for reference. – BlackVegetable Nov 08 '13 at 15:44
  • This won't run to 9999, it will run to 9998. Use <= instead of < or change 9999 to 10000 – Sterling Archer Nov 08 '13 at 15:45
  • My method doesn't return a result of type boolean. – JackDee Nov 08 '13 at 15:45
  • @JackDee that means that `n%d` are leaving remainders and it's skipping over and returning nothing – Sterling Archer Nov 08 '13 at 15:47
  • Your WHILE loop looks like a loop, but it is not. The very first time inside the loop, you check some condition and either way you return true/false. So, you need to fix that The reason you are getting a syntax error is because you are not returning anything if control NEVER flows into the loop. – Darius X. Nov 08 '13 at 15:49
  • What should isPerfectNumber do? Why does it require TWO arguments? The name 'isPerfectNumber' suggests that it tests if a certain number is perfect, so what is the second parameter for? – isnot2bad Nov 08 '13 at 16:05
  • @isnot2bad the second parameter is to check if d is the divisor. For every n, by using brute force approach, its divisor might range from 1 to 9999, here I only put 2 to n-1. – JackDee Nov 08 '13 at 16:09

2 Answers2

1

Looking at the code in your case will return false most of the times. I think what you were looking for is a bit wrong. Because d is smaller than n, and n divided by d will always be grater than 0. Also in that loop you never change the value of d.

A solution might be:

     public void run() {
            for (int n = 1; n < 9999; n++) 
{           spd=1;                                                         
                for (int d = 2; d <= n/2; d++) { //no need to go further than n/2
                    //d is the potential divisor of n, ranging from 2 to n-1,// 
                if(n%d==0) spd+=d; //if n divides by d add it to spd.

            }
            if(spd==n) print(n);
        }

Try this and let me know if it works for you.

I find something cool here : http://en.wikipedia.org/wiki/List_of_perfect_numbers. You should the much faster using this formula: 2^(p−1) × (2^p − 1). You can see the formula better on the wikilink.

sir_k
  • 332
  • 3
  • 18
  • My bad, the code is a bit wrong, try the updated version. I has to be less or equal to n/2 rather that just less. Hope this makes sense. – sir_k Nov 08 '13 at 16:31
  • Yes. I got it. That's what I was about to say. – JackDee Nov 08 '13 at 16:34
  • One more thing, what do you mean n divided by d will always be greater than 0? n % d == 0 checks if d is the divisor. – JackDee Nov 08 '13 at 16:46
  • Initially the code was n/d. Maybe I saw it wrong. The while loop you are using its wrong because you are not chaing the value of d inside, and at the end of the execution you force the method to return a true false value. I can explain you why you code does not work and how to fix it if you want. – sir_k Nov 08 '13 at 16:48
  • Another question. Does the two FOR loops work this way: count n from 1 to 9999, and in every counted n count d from 2 to n - 1. For example, n will only continues counting from 6 to 7 if d has counted from 2 to 5. Hope you understand. Because I wrote another code before, and it seemed working. Thanks. – JackDee Nov 08 '13 at 16:49
  • Yes, that is correct. You have to nested for loops. So for every n, you do another for loop from 2 to n/2. This is why I think you should try the formula from the wikilink. In 4 for iterations you get all the numbers. Do you want me to put some code for it? – sir_k Nov 08 '13 at 16:51
  • Thanks. You are welcome to do that. But I will try it myself. – JackDee Nov 08 '13 at 16:57
  • Cool, try it and put it here if it's not working and I'll have a look at it. – sir_k Nov 08 '13 at 17:03
0

Method isPerfect should probably be something like that:

public static boolean isPerfect(int number) {
    int s = 1;
    int d = number / 2;
    for(int i = 2; i <= d; i++) {
        if (number % i == 0) s += i;
    }
    return s == number;
}
isnot2bad
  • 24,105
  • 2
  • 29
  • 50