-1

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?

Community
  • 1
  • 1
Toko Laskis
  • 23
  • 1
  • 1
  • 5
  • 1
    What is `forrige` for? `i` will always be less than or equal to `28123`, so you set all of the values in your array to `0`. – Blender Mar 17 '13 at 21:45
  • @Blender: no, I did not. forrige is to get the previous value in the for-loop. All values in my array is not set to 0, that is incorrect. – Toko Laskis Mar 17 '13 at 21:49
  • Oh, crap, sorry, you're right. I forgot to set forrige = i at the end of the loop. – Toko Laskis Mar 17 '13 at 21:50
  • I still seem to get the wrong answer, although `forrige = i` is set at the end of the loop. – Toko Laskis Mar 17 '13 at 21:52
  • How does your code check to see if a number is the sum of any two abundant numbers less than 28123? – Blender Mar 17 '13 at 21:54
  • @Blender, I start to see the error in my logic here. While I have just checked the n1 * 2 and n1 + n2, I have forgot n1 + n3 etc. Will come back tomorrow and write some new code. – Toko Laskis Mar 17 '13 at 22:00
  • Really. First think what you want to do, then try on the PC, and later come here asking for help. Skipping the first step is sheldom a good idea (there is no point in doing hundreds of euler problems if we end doing them for you). – SJuan76 Mar 17 '13 at 22:04
  • Seeing as I had been stuck for several hours, I did not see the point in sitting there being stuck. I never asked for you to write any code, I asked for pointers that would expose the errors in my logic. Which I did achieve. I fail to see your problem. – Toko Laskis Mar 17 '13 at 22:09
  • Because nobody cares if you get the solution. What it matters is that you are capable of, having a problem, to take the steps needed to think how to solve it. What you did was just write some dumb code without thinking and ask other people to solve it for you (your solution has not the slightest sense). If you can not understand the issue, your boss will, do not worry. – SJuan76 Mar 17 '13 at 22:16
  • I think you lack a basic understanding of cognitive ability. For someone like me who have been programming for three days, getting into this mindset takes time. If you look subjectively at it, the only mistake I made was that I failed to add ALL the sums of abundant numbers, seeing as I only added n * 2 and n + (n -1). Sites like these are a great tool to get pointers so that you'll get on the right track, and thanks to them, I've been able to develop relatively quickly. Everyone learns differently, and you fail to see that. – Toko Laskis Mar 17 '13 at 22:28

2 Answers2

0

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.

SJuan76
  • 24,532
  • 6
  • 47
  • 87
  • Mathematically speaking, can't I just: 1. find the abundant number 2. multiply it by two. that number is the sum of two abundant numbers. 3. add the abundant number to the previous abundant number. that number is the sum of two abundant numbers. I fail to see the error in that logic. – Toko Laskis Mar 17 '13 at 21:58
  • As you explain it, you will find **some** numbers that are the sum of two abundant numbers. That is not what is being asked. You would have to ensure that you make all the possible sums – SJuan76 Mar 17 '13 at 22:01
0

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.
Blender
  • 289,723
  • 53
  • 439
  • 496