Question

I have been working on the problem below but I get the wrong answer. What is wrong with my logic?

A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.

A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.

As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.

Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.

Here is my code:

   public class EulerProblem23 {
public static void main(String[] args) {
    
    //First, I create an array containing all the numbers ranging from 1 to 28123.
    int[] tall = new int[28123];
    int x = 0;
    for (int j = 1;j<=28123;j++){ 
        tall[x] = j;
        x++;
    }
    
    //Then, give all the numbers that can be written as the sum of two abundant numbers
    //the value 0.
    int forrige = 0;
    for (int i = 1;i<=28123;i++){
        if (isAbundant(i)){
            if (2 * i <= 28123){
                tall[i - 1] = 0;
            }
            if (forrige + i <= 28123){
                tall[i - 1] = 0;
            }
        }
    }
    
    //All that's left should be summing all the numbers in the array.
    
    long sum = 0;
    for (int y = 0;y<28123;y++){
        sum += tall[y];
    }
    
    System.out.println(sum);    
    
}

public static boolean isAbundant(int n){
    int sumAvDivisorer = 0;
    for (int i = 1;i<n;i++){
        if (n % i == 0){
            sumAvDivisorer += i;
        }
    }
    
    if (sumAvDivisorer > n){
        return true;
    }
    else {
        return false;
    }
}
    }

Is there something wrong with my logic here? Wouldn't all of the integers that can be defined as the sum of two abundant numbers become 0?

Was it helpful?

Solution

I would do it like this:

  • Make an array of all abundant numbers.
  • Add all pairs together. You can do this with nested for loops.
  • For every pair that adds to a number less than or equal to 28123, add the sum of that pair to the total sum.

OTHER TIPS

This code makes no sense:

//Then, give all the numbers that can be written as the sum of two abundant numbers
//the value 0.
int forrige = 0;
for (int i = 1;i<=28123;i++){
    if (isAbundant(i)){
        if (2 * i <= 28123){
            tall[i - 1] = 0;
        }
        if (forrige + i <= 28123){
            tall[i - 1] = 0;
        }
    }
}

Supposedly, what you want to know if, for each i in the loop, if there are two numbers j and k which are both abundant and such that j + k = i.

Your code has no relation with it. Also, the second if has little meaning, as forrige is always 0.

What I would do.

1) An array of booleans [0, 28123]. True if the number is abundant (previous step). (*)

2) Another array [0, 28123]. True if the number in the position is the add of two abundant numbers. Loop i from 1 to 28123, for each i, loop z from 1 to i/2 (either j <= i/2 or k <= i / 2). For each z, check in the previous array for z and i-z, if both are true set the value to true.

3) Loop the previous array and add all the indexes that are true in the array.

Alternatively, is the condition of "abundant" is sparse enough, you could replace 1) with a list of the numbers which are abundant, and a hashset of them. So, instead of running j from 1 to i/2, you loop this list until you get to i/2 (use the hashset to find quickly if i-j is abundant or not).

Anyway, the idea in this problem is precalculating the values that you will be using again and again, instead of repeating the isAbundant calls to the same values time after time.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top