Perfect Numbers.
i'm trying to get this code to print perfect numbers below 500, which are 6, 28, 496.
for example, 6 is a perfect number because all its factors(1,2,3 ) add up to 6.
There are no compiler errors but the problem is the output:
6 is a perfect number
15 is a perfect number
28 is a perfect number
66 is a perfect number
91 is a perfect number
153 is a perfect number
190 is a perfect number
276 is a perfect number
435 is a perfect number
496 is a perfect number
The output does include 4,28 and 496, but the rest is incorrect.
Does anyone know what i need to change?
class PerfectNumbersTwo{
publicstaticvoid main(String[] args){
int num = 1, elements = 0, sum = 0, p = 0, sumzx = 0, sumaz = 0;
while( num < 500){
for(int y = 1; y <num; y++)
if(num % y == 0) elements +=1;
int[] factors =newint[elements];
for(int y = 1; y ><num; y++)
if(num % y == 0) factors[p++] = y;
for(int y = 0; y >< factors.length; y++){
if(PrimeNumSequence.isPrime(factors[y]) && factors[y] > 2){
sumzx = factors[y] * factors[y-1];
sumaz = factors[y-1] * 2;
sumaz = sumaz - 1;
}
if(sumzx == num && sumaz == factors[y])
System.out.println(num+" is a perfect number");
}//close for.
num++;
}//close while.
}
}
[2430 byte] By [
mark_8206a] at [2007-11-27 0:19:27]

Hi Mark,
I see a lot of if- and for-statements without proper opening and closing brackets. I also see a lot of meaningless variable names (p, sumzx, sumaz). You have also stuffed everything inside your main method which is, obviously, not the way to program in Java! One last thing: I see you're doing something with with an isPrime(...) method while to check for a perfect number, primes have little to do with it.
So, I'm not going to assist you with your current code (sorry to say but I think no one can/will help you with that), but I will give you a start on how to do it more OO by using some methods:
class PerfectNumbersTwo {
public static boolean isPerfect(int n) {
// if n equals sumFactors(n) AND n is more than 1,
// the number is perfect, return true, in all other cases
// return false.
}
public static int sumFactors(int n) {
int sum = 1;
// loop from 2 to n/2 and sum all the divisors
// of 'n' and add them to 'sum'
return sum;
}
public static void main(String[] args) {
for(int i = 0; i <= 500; i++) {
if(isPerfect(i)) {
System.out.println(i);
}
}
}
}
Good luck!
> Hi Mark,
>
> I see a lot of if- and for-statements without proper
> opening and closing brackets. I also see a lot of
> meaningless variable names (p, sumzx, sumaz). You
> have also stuffed everything inside your main method
> which is, obviously, not the way to program in Java!
> One last thing: I see you're doing something with
> with an isPrime(...) method while to check for a
> perfect number, primes have little to do with it.
>
> So, I'm not going to assist you with your current
> code (sorry to say but I think no one can/will help
> you with that), but I will give you a start on how to
> do it more OO by using some methods:
prome thanks for the reply, you were the only one! but the whole prime number thing is supposed to be there!
my thinking behind the code i posted is this.
take the number 28, it can be divided by 1,2, 4, 7,14
the first prime factor after 2 is 7. the number before 7 is 4.
7 * 4 = 28(the original number) and also
4 * 2 - 1 = 7; (multiply the number before the prime by 2, then subtract one)
both those calculations mean that any number is perfect.(i think, not 100% sure!)
you could do the same for 6.
its factors are 1,2,3.
3*2 = 6. (3 the first prime after 2, 2 is also the number before 3)
2*2 - 1 = 3. (multiply the number before the prime by two, then subtract one).
that's how i'm trying to print out perfect numbers.
> take the number 28, it can be divided by 1,2, 4, 7,14
> the first prime factor after 2 is 7. the number before 7 is 4.
> 7 * 4 = 28(the original number) and also 4 * 2 - 1 = 7;
> (multiply the number before the prime by 2, then subtract one)
> both those calculations mean that any number is
> perfect.(i think, not 100% sure!)
Care to elaborate on that Kaballah?
kind regards,
Jos
JosAHa at 2007-7-11 22:11:07 >

> ...
> prome thanks for the reply, you were the only one!
> but the whole prime number thing is supposed to be
> there!
> my thinking behind the code i posted is this.
You're welcome.
> take the number 28, it can be divided by 1,2, 4,
> 7,14
> the first prime factor after 2 is 7. the number
> before 7 is 4.
> 7 * 4 = 28(the original number) and also
> 4 * 2 - 1 = 7; (multiply the number before the prime
> by 2, then subtract one)
> both those calculations mean that any number is
> perfect.(i think, not 100% sure!)
No, a number n is perfect if the sum of it's factors (up to n itself) equals 2*n, so
6 is perfect because it's factors summed = 1 + 2 + 3 + 6 = 12 = 2*6
28 is perfect because it's factors summed = 1 + 2 + 4 + 7 + 14 + 28 = 56 = 2*28
496 is perfect because it's factors summed = 1 + 2 + 4 + 8 + 16 + 31 + 62 + 124 + 248 + 496 = 992 = 2*496
http://mathworld.wolfram.com/PerfectNumber.html
> ...> Care to elaborate on that Kaballah?> > kind regards,> > JosHe's still working on a proof, I guess.; )
> No, a number n is perfect if the sum of it's
> factors (up to n itself) equals 2*n,
> so
> 6 is perfect because it's factors summed = 1 + 2 + 3
> + 6 = 12 = 2*6
> 28 is perfect because it's factors summed = 1 + 2 +
> 4 + 7 + 14 + 28 = 56 = 2*28
> 496 is perfect because it's factors summed = 1 + 2 +
> 4 + 8 + 16 + 31 + 62 + 124 + 248 + 496 = 992 = 2*496
>
> http://mathworld.wolfram.com/PerfectNumber.html
Yeah, i actually have another class that calculates perfect numbers that way and it even works.
but if you look at the output from post 1, i'm not that far away from being right, my perfect number theory may still be correct!!
if(num % y == 0) elements +=1;I think you need to reset elements to 0 before every new start , right ?
rym82a at 2007-7-11 22:11:07 >

> ...
> Yeah, i actually have another class that calculates
> perfect numbers that way and it even works.
> but if you look at the output from post 1, i'm not
> that far away from being right, my perfect number
> theory may still be correct!!
I don't think so, but good luck with your proof!
; )
> > ...
> > Yeah, i actually have another class that
> calculates
> > perfect numbers that way and it even works.
> > but if you look at the output from post 1, i'm not
> > that far away from being right, my perfect number
> > theory may still be correct!!
>
> I don't think so, but good luck with your proof!
> ; )
I think he's right about that: let N be a perfect number and let the
sequence 1, 2, ... d, p ... N be all the distinct divisors of which p is the
smallest prime > 2. The divisor d must be a power of two then and from
(6) ... (14) from the Wolfram link it shows that p must be a Mersenne
prime. It's a corollary in a very cryptic form.
I like it; I'm going to use that for spoiling boring birthday parties ;-)
kind regards,
Jos
JosAHa at 2007-7-11 22:11:07 >

so josah do you have any idea what i need to change in the code from post 1?
> so josah do you have any idea what i need to change
> in the code from post 1?
I think (and this is just programming stuff) that you should use a
List<Integer> for all the distinct divisors and I also think that your
conclusion is wrong: that first prime number > 2 should not just be a
prime number, it should also be a Mersenne prime number.
and even then I don't know if you can say that if 2^n*MP == P that
P must be a perfect number (gotta scribble a bit on that one).
kind regards,
Jos
JosAHa at 2007-7-11 22:11:07 >

> ...> and I also think that your > conclusion is wrong: that first prime number > 2 should not just be a > prime number, it should also be a Mersenne prime> number.> > ...[ removed a wrong spasm of my brain ]
sumzx = factors[y] * factors[y-1]; this line from my code is supposed to multiply the array element, y, by the element before y in the array.so if the array named factors is: 1,2,4,7if y is 7, then would that line of code multiply 7 by 4?
I'm *still* trying to get my code to print out perfect numbers below 500 which are 6,28, and 496.
6 = 1 + 2 + 3,
28 = 1 + 2 + 4 + 7 + 14,
496 = 1 + 2 + 4 + 8 + 16 + 31 + 62 + 124 + 248
the factors of 6, 28, and 496 have all prime numbers greater than 2.
take the factors of 28 for example, the first prime number after 2 is 7.
If you multiply 7 by the factor that precedes it,(4), 7*4 = 28.
and also 4 * 2 - 1 = 7.
you can do the same with the factors of 496 and 3.
the first prime after 2 is 31.
31*16 = 496
16 * 2 - 1 = 31.
so i'm trying to write code to print perfect numbers based on this pattern.
The problem is the output, it says that 15,66,91,153,190,276,435, are perfect numbers, which is incorrect.
does anyone know what is wrong with this code? it's almost correct!
class PerfectNumbersTwo {
public static void main(String[] args) {
int num = 1, elements = 0, sum = 0, p = 0, sumzx = 0, sumaz = 0;
while( num < 500) {
for(int y = 1; y <num; y++) {
if(num % y == 0) elements +=1;
}
int[] factors = new int[elements];
for(int y = 1; y ><num; y++) {
if(num % y == 0) factors[p++] = y;
}
for(int y = 0; y >< factors.length; y++) {
if(PrimeNumSequence.isPrime(factors[y]) && factors[y] > 2) {
sumzx = factors[y] * factors[y-1];
sumaz = factors[y-1] * 2;
sumaz = sumaz - 1;
}
if(sumzx == num && sumaz == factors[y])
System.out.println(num+" is a perfect number");
} //close for.
num++;
} //close while.
}
}
output
6 is a perfect number
15 is a perfect number
28 is a perfect number
66 is a perfect number
91 is a perfect number
153 is a perfect number
190 is a perfect number
276 is a perfect number
435 is a perfect number
496 is a perfect number
> I'm *still* trying to get my code to print out
> perfect numbers below 500 which are 6,28, and 496.
>
> ...
And I'm still telling you to separate things into decent methods (what Jos also suggested).
But according to your logic, 10 should also be a perfect number then.
The distinct divisors of 10 are: 1, 2 and 5
the first prime > 2 is 5. The number before 5 is 2, and 5*2 == 10, so it's a perfect number.
> But according to your logic, 10 should also be a
> perfect number then.
>
> The distinct divisors of 10 are: 1, 2 and 5
>
> the first prime > 2 is 5. The number before 5 is 2,
> and 5*2 == 10, so it's a perfect number.
no prome!! you're missing the second part of the theory! :) (multiply the factor before the prime by 2 then subtract one).
take the factors of 28.
28 = 1 + 2 + 4 + 7 + 14,
the fist prime after 2 is 7. before 7 is 4.
4 * 2 = 8 - 1 = 7. (7 the first prime after 2).
the same for the factors of 6
1,2,3
first prime after 2 is 3, factor before 3 is 2
2*2 - 1 = 3. (3 the first prime after 2)
but the factors of 10
1,2,5
2*5 = 10,
but
2*2-1 does not equal 5.
therefore 10 is not a perfect number!
> > But according to your logic, 10 should also be a
> > perfect number then.
> >
> > The distinct divisors of 10 are: 1, 2 and 5
> >
> > the first prime > 2 is 5. The number before 5 is
> 2,
> > and 5*2 == 10, so it's a perfect number.
>
> no prome!! you're missing the second part of the
> theory! :) (multiply the factor before the prime by 2
> then subtract one).
; )
So I did!
Well, here's a OO-style solution:
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
class PerfectNumbersTwo {
public static boolean isPerfect(int n) {
List<Integer> divisors = getDivisor(n);
int primeIndex = getIndexOfPrimeLargerThan(2, divisors);
if(primeIndex > 0) {
int beforePrime = divisors.get(primeIndex-1).intValue();
int prime = divisors.get(primeIndex).intValue();
return (((beforePrime*2)-1) == prime) ? n == (beforePrime*prime) : false;
} else {
return false;
}
}
public static List<Integer> getDivisor(int n) {
List<Integer> divisors = new ArrayList<Integer>();
for(int i = 1; i <= n/2; i++) {
if(n%i == 0) { divisors.add(new Integer(i)); }
}
return divisors;
}
public static Integer getIndexOfPrimeLargerThan(int n, List<Integer> numbers) {
for(int i = 0; i < numbers.size(); i++) {
int temp = numbers.get(i).intValue();
BigInteger bi = new BigInteger(String.valueOf(temp));
if(bi.isProbablePrime(100) && temp > n) {
return i;
}
}
return -1;
}
public static void main(String[] args) {
for(int i = 0; i <= 500; i++) {
if(isPerfect(i)) {
System.out.println(i);
}
}
}
}
prome thanks a lot for that code, but i'm getting compiler errors, maybe it's something to do with those packages, should i be able to use them with jdk version 1.4.1?
PerfectNumbersTwo.java:19: <identifier> expected
public static List<Integer> getDivisor(int n) {
^
PerfectNumbersTwo.java:44: ';' expected
}
^
PerfectNumbersTwo.java:8: cannot resolve symbol
symbol : variable List
location: class PerfectNumbersTwo
List<Integer> divisors = getDivisor(n);
^
PerfectNumbersTwo.java:8: cannot resolve symbol
symbol : variable Integer
location: class PerfectNumbersTwo
List<Integer> divisors = getDivisor(n);
^
PerfectNumbersTwo.java:8: cannot resolve symbol
symbol : variable divisors
location: class PerfectNumbersTwo
List<Integer> divisors = getDivisor(n);
^
PerfectNumbersTwo.java:8: cannot resolve symbol
symbol : method getDivisor (int)
location: class PerfectNumbersTwo
List<Integer> divisors = getDivisor(n);
^
PerfectNumbersTwo.java:9: cannot resolve symbol
symbol : variable divisors
location: class PerfectNumbersTwo
int primeIndex = getIndexOfPrimeLargerThan(2, divisors);
^
PerfectNumbersTwo.java:11: cannot resolve symbol
symbol : variable divisors
location: class PerfectNumbersTwo
int beforePrime = divisors.get(primeIndex-1).intValue();
^
PerfectNumbersTwo.java:12: cannot resolve symbol
symbol : variable divisors
location: class PerfectNumbersTwo
int prime = divisors.get(primeIndex).intValue();
^
9 errors
For java 1.4 you will not be able to use generic containers such as List<T>. You'll have to use nongeneric containers such as ArrayList with casts. Also you might want to look up autoboxing and unboxing. This is allowed in higher versions of Java but not in 1.4. You will need to explicitly change Integer to int and visa versa.
import java.math.BigInteger;
import java.util.ArrayList;
// translated to work w/ Java 1.4
class PerfectNumbersThree
{
public static boolean isPerfect(int n)
{
ArrayList myDivisors = getDivisor(n);
int primeIndex = getIndexOfPrimeLargerThan(2, myDivisors);
if (primeIndex > 0)
{
int beforePrime = ((Integer) myDivisors.get(primeIndex - 1)).intValue();
int prime = ((Integer) myDivisors.get(primeIndex)).intValue();
return (((beforePrime * 2) - 1) == prime) ? n == (beforePrime * prime): false;
}
else
{
return false;
}
}
public static ArrayList getDivisor(int n)
{
ArrayList myDivisors = new ArrayList();
for (int i = 1; i <= n / 2; i++)
{
if (n % i == 0)
{
myDivisors.add(new Integer(i));
}
}
return myDivisors;
}
public static int getIndexOfPrimeLargerThan(int n, ArrayList myNumbers)
{
for (int i = 0; i < myNumbers.size(); i++)
{
int temp = ((Integer) myNumbers.get(i)).intValue();
BigInteger bi = new BigInteger(String.valueOf(temp));
if (bi.isProbablePrime(100) && temp > n)
{
return i;
}
}
return -1;
}
public static void main(String[] args)
{
for (int i = 0; i <= 500; i++)
{
if (isPerfect(i))
{
System.out.println(i);
}
}
}
}
null
> prome thanks a lot for that code, but i'm getting
> compiler errors, maybe it's something to do with
> those packages, should i be able to use them with jdk
> version 1.4.1?
>...
You need JDK 1.5+ for my code to work.
Here's a pre-generics solution:
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
class PerfectNumbersTwo {
public static boolean isPerfect(int n) {
List divisors = getDivisor(n);
int primeIndex = getIndexOfPrimeLargerThan(2, divisors);
if(primeIndex > 0) {
int beforePrime = ((Integer)divisors.get(primeIndex-1)).intValue();
int prime = ((Integer)divisors.get(primeIndex)).intValue();
return (((beforePrime*2)-1) == prime) ? n == (beforePrime*prime) : false;
} else {
return false;
}
}
public static List getDivisor(int n) {
List divisors = new ArrayList();
for(int i = 1; i <= n/2; i++) {
if(n%i == 0) { divisors.add(new Integer(i)); }
}
return divisors;
}
public static Integer getIndexOfPrimeLargerThan(int n, List numbers) {
for(int i = 0; i < numbers.size(); i++) {
int temp = ((Integer)numbers.get(i)).intValue();
BigInteger bi = new BigInteger(String.valueOf(temp));
if(bi.isProbablePrime(100) && temp > n) {
return i;
}
}
return -1;
}
public static void main(String[] args) {
for(int i = 0; i <= 500; i++) {
if(isPerfect(i)) {
System.out.println(i);
}
}
}
}
> For java 1.4 you will not be able to use generic> containers such as List<T>. You'll have to use> nongeneric containers such as ArrayList with casts.> ...You can still define them as a List instead of an ArrayList.
> > For java 1.4 you will not be able to use generic
> > containers such as List<T>. You'll have to use
> > nongeneric containers such as ArrayList with
> casts.
> > ...
>
> You can still define them as a List instead of an
> ArrayList.
ok, thanks for all that, i'll have to take a closer look at it so i know what's going on, i've never used a couple of those packages before.
but now that i think i've convinced you that what i was trying to do is correct, do you know why the output for my code in reply 14 is not what i want it to be, it's close to printing out the three perfect numbers below 500, but there's obviously some error.
>You can still define them as a List instead of an ArrayList.Yep I agree. You just can't call a List constructor since it is an interface and not a concrete class.Message was edited by: petes1234
> >You can still define them as a List instead of an
> ArrayList.
>
> Yep I agree. You just can't call a List constructor
> since it is an interface and not a concrete class.
Of course. But if you define them as being a List and wanted to change that specific implementation, you'd only have to change one line of code: the instantiation of the ArrayList in the getDivisor(...) method. Whereas in your code, you'd have to change 4 lines of code.
; )
does anyone know what i need to change in my code in reply 14?i want it to print6 is a perfect number28 is a perfect number496 is a perfect number
> does anyone know what i need to change in my code in
> reply 14?
> i want it to print
> 6 is a perfect number
> 28 is a perfect number
> 496 is a perfect number
Don't take this the wrong way, but like I said in my first reply: your code is very messy: dubious variable names, everything in one method, a call to a class which is not in the standard Java API, lack of proper opeming/closing brackets...
So sorry, I'm not going to look at that (nor will anyone else is my guess).
Good luck anyway.
Your code is not working because it needs to stop checking after it hits that first prime after 2. It is not doing this but rather keeps right on checking./Pete
Something like this may work:
import java.util.*;
class PerfectNumbersTwo
{
public static void main(String[] args)
{
List myFactors = new ArrayList();
for (int num = 2; num < 500; num++)
{
int factor1 = 1;
int factor2 = 1;
int sumzx = 0;
int sumaz = 0;
boolean keepChecking = true;
int y = 1;
//for (int y = 1; y < num; y++)
while (keepChecking)
{
if (num % y == 0)
{
factor1 = factor2;
factor2 = y;
if (PrimeNumSequence.isPrime(factor2) && factor2 > 2)
{
keepChecking = false;
sumzx = factor2 * factor1;
sumaz = factor1 * 2 - 1;
if (sumzx == num && sumaz == factor2)
{
System.out.println(num + " is a perfect number");
}
}
}
y++;
if (y == num)
{
keepChecking = false;
}
}
}
}
}
> ... (nor will anyone else is my guess).> ...I was wrong again it seems!; )
> > ... (nor will anyone else is my guess).
> > ...
>
> I was wrong again it seems!
> ; )
Thanks a lot petes! that's great.
prome i'm sure you're right about the variables etc but i'd spent hours trying to figure out what's wrong with the code, so i had to try to finish it off. (or should i say petes had to finish it).
This line:List myFactors = new ArrayList(); is an unnecessary relic from a prior attempt of mine. It is not necessary.
One more thing, if I were to code something like this from scratch, I'd try to give my variables more meaningful names. Something like this:
class PerfectNumbersTwo
{
public static void main(String[] args)
{
for (int numberToCheck = 1; numberToCheck < 10000; numberToCheck++)
{
int priorFactor = 1;
int factor = 1;
int factorTimesPriorFactor = 0;
int twicePriorFactorLess1 = 0;
boolean keepChecking = true;
int possibleFactor = 1;
while (keepChecking)
{
if (numberToCheck % possibleFactor == 0)
{
priorFactor = factor;
factor = possibleFactor;
if (PrimeNumSequence.isPrime(factor) && factor > 2)
{
keepChecking = false;
factorTimesPriorFactor = factor * priorFactor;
twicePriorFactorLess1 = priorFactor * 2 - 1;
if (factorTimesPriorFactor == numberToCheck && twicePriorFactorLess1 == factor)
{
System.out.println(numberToCheck + " is a perfect number");
}
}
}
possibleFactor++;
if (possibleFactor >= numberToCheck)
{
keepChecking = false;
}
}
}
}
}
> One more thing, if I were to code something like this> from scratch, I'd try to give my variables more> meaningful names. ...And methods, I hope.
thanks for all the advice, as u have both noticed i usually don't worry too much about the variable names etc, i'll try to improve on that
> And methods, I hope. True.