0

I have to write a method int sumBeyond(int k) to find the least n such that the sum of the natural numbers smaller than n exceeds k. However, when I try to test the method it doesn't return any value.

public static int sumBeyond(int k){
    int i=1;
    int sum=0;
    while(i<k){
        sum=sum+i;
        i=i+1;
    }
    return sum;
}

I tried calling the function this way, in the main method:

sumBeyond(100);
  • How do you know it doesn't return anything if you just ignore the return value in your example. Have you tried something like `int myReturn = sumBeyond(100); System.out.println(myReturn);`? – OH GOD SPIDERS Jan 03 '20 at 13:08
  • 2
    It definitely returns a value, but if you only call `sumBeyond(100);` you won't see any output... Make it `System.out.println(sumBeyond(100));`. – deHaar Jan 03 '20 at 13:08
  • 1
    I would write `while(sum – Arnaud Denoyelle Jan 03 '20 at 13:10
  • 1
    @ArnaudDenoyelle also it should return i (or perhaps i+1 or i-1, no time to think on it now) not sum. – Jeremy Kahan Jan 03 '20 at 14:00

3 Answers3

5
int sum100 = sumBeyond(100);
System.out.println("Sum is " + sum100);

Then small improvements:

public static int sumBeyond(int k) {
    int i = 1;
    int sum = 0;
    while (i < k) {
        sum += i;
        ++i;
    }
    return sum;
}

public static int sumBeyond(int k) {
    int sum = 0;
    for (int i = 1; i < k; ++i) {
        sum += i;
    }
    return sum;
}

public static int sumBeyond(int k) {
    // return (k - 1) * (1 + k - 1) / 2;
    return (k - 1) * k / 2;
}

To solve the problem stated:

  • Find n such that sum upto n-1 >= k' where k' is k - 1.
  • Sum upto n-1 is (n - 1) * n / 2 >= k'

So we get:

x² - x - 2k'
------------  >=  0
     2

Solution for = 0:

a = 1/2
b = -1/2
c = -2k'
            _________
    -b +/- V b² - 4ac
x = ------------------
          2a

 x = 1/2 +/- sqrt(1/4 + 4k'/4) =
   = 1/2 +/- 1/2 . sqrt(1 + 4k')

Positive x

 x = 1/2 + 1/2 . sqrt(4k' + 1)

public static int sumBeyond(int k) {
    double x = (Math.sqrt(4 * (k-1) + 1) + 1) / 2;
    return (int) Math.ceil(x);
}

The solution should be given the math as comment.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
  • Another improvement I just wanted to point out for OP too, could be changing it to a `for` loop for readability, since that is basically what he is doing with `i` anyway. – Nexevis Jan 03 '20 at 13:13
  • 1
    @Nexevis yes, added it; probably a new language construct. – Joop Eggen Jan 03 '20 at 13:15
  • @Turing85 I was just at it, though that is more math insight: an _intelligent_ solution, we programmers not always ... – Joop Eggen Jan 03 '20 at 13:17
  • 1
    The math is elegant, but the problem statement is "find the least n such that the sum of the natural numbers smaller than n exceeds k." Why return sum? But actually, we need something like while (sum < k), as @ArnaudDenoyelle commented – Jeremy Kahan Jan 03 '20 at 13:57
  • @JeremyKahan you are right of course. I have added a solution with a quite rough math. – Joop Eggen Jan 03 '20 at 14:13
  • 1
    Nice. I had sketched out an approach with the quadratic formula, too. There's a case I want to test, because where the root came out evenly so that it was its Math.ceil(), I thought I had to add 1 (also in that case I was a bit worried about floating point errors). – Jeremy Kahan Jan 03 '20 at 16:29
  • @JeremyKahan yes the normal floating point blues, and also "exceed" - `>` - is a bit irritating. About your floating point errors: that _is_ serious. In a similar problem, I checked the square of the root ("smart numbers"). – Joop Eggen Jan 03 '20 at 16:44
  • I just ran this, and I'm not liking the answers. For 0 it returns 0, and I would argue it should return 2, since to exceed 0 the sum needs to be 1, which is the sum of natural numbers less than 2. But aside from that, it is returning different values for 7 and 8, which in any case should have the same answer since 1 + 2 + 3 < 7 < 8 < 1+2+3+4 – Jeremy Kahan Jan 03 '20 at 18:06
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/205310/discussion-between-jeremy-kahan-and-joop-eggen). – Jeremy Kahan Jan 03 '20 at 18:30
1

If I got your question right, you want to find the least n such that the sum of the natural numbers smaller than n exceeds k and thus, you shouldn't return the sum itself, because it is not n but needs to be calculated in order to find the smallest n.

You can do it the following way:

public static int sumBeyond(int k) {
    int n = 0;
    int sum = 0;

    for (int i = 0; i < k; i++) {
        // provide an intermediate sum (the one before this step) for logging purpose
        int intermediateSum = sum;
        // sum up
        sum += i;
        // set the return value to the current "natural number"
        n = i;
        // print some detailed debug log
        System.out.println("sum:\t" + sum +
                " (" + intermediateSum + " + " + i +  ")\t——>\tn = " + n);

        // exit the loop if the sum is greater than k
        if (sum >= k) {
            break;
        }
    }

    return n + 1;
}

Calling it in a main like this

public static void main(String[] args) {
    int k = 100;
    System.out.println("The least n" +
            + "such that the sum of the natural numbers smaller than n exceeds "
            + k + " is " + sumBeyond(k));
}

will print

sum:    0 (0 + 0)       ——> n = 0
sum:    1 (0 + 1)       ——> n = 1
sum:    3 (1 + 2)       ——> n = 2
sum:    6 (3 + 3)       ——> n = 3
sum:    10 (6 + 4)      ——> n = 4
sum:    15 (10 + 5)     ——> n = 5
sum:    21 (15 + 6)     ——> n = 6
sum:    28 (21 + 7)     ——> n = 7
sum:    36 (28 + 8)     ——> n = 8
sum:    45 (36 + 9)     ——> n = 9
sum:    55 (45 + 10)    ——> n = 10
sum:    66 (55 + 11)    ——> n = 11
sum:    78 (66 + 12)    ——> n = 12
sum:    91 (78 + 13)    ——> n = 13
sum:    105 (91 + 14)   ——> n = 14
The least n such that the sum of the natural numbers smaller than n exceeds 100 is 15

I really hope I got this right, still not sure...
Oh, and if 0 is not a natural number, start iterating at 1.

deHaar
  • 17,687
  • 10
  • 38
  • 51
  • So regardless of whether 0 is natural, "the least n such that the sum of the natural numbers smaller than n exceeds 100 is 14" is not correct. The sum of the natural numbers smaller than (note not <=) 14 is 91. sumBeyond(100) should return 15. – Jeremy Kahan Jan 03 '20 at 17:44
  • @JeremyKahan sure, you're right... Corrected – deHaar Jan 03 '20 at 18:38
0

So as has been noted above, the issue was not that your method was not returning something, but that you were doing nothing with what was returned. Also, as noted above, you were focused on finding the sum, but that is not actually what the question asked. I am sympathetic to your use of a while loop here since it may not execute at all and since you don't know a priori how many times it will run. So I rewrote it to check the right things and adapted the main from deHaar to exercise it. That allowed me to hand check the answers, because some of the cases of equality and need for "numbers less than" rather than "numbers less than or equal to" were subtle. The math teacher in me really likes the quadratic formula approach from Joop Eggen; it's just harder to get right (and indeed, if I were going to do it, I would end up testing that it's consistent with what I have here).

public class ShadesOfLittleGauss {
    public static int sumBeyond(int k) {
        int i = 1; //have summed (trivially) all natural numbers less than 1 so far
        int sum = 0;
        while (sum <= k) { //needs to exceed, so <=
            sum = sum + i;
            i = i + 1;
        }
        return i;
    }
public static void main(String[] args) {
    for (int k = -1; k < 10; k++) {
        System.out.println("The least number " +
            "such that the sum of the natural numbers smaller than n exceeds " +
            k + " is " + sumBeyond(k));

    }
}
}

output (you can hand check these are correct as stated):

The least number such that the sum of the natural numbers smaller than n exceeds -1 is 1
    The least number such that the sum of the natural numbers smaller than n exceeds 0 is 2
    The least number such that the sum of the natural numbers smaller than n exceeds 1 is 3
    The least number such that the sum of the natural numbers smaller than n exceeds 2 is 3
    The least number such that the sum of the natural numbers smaller than n exceeds 3 is 4
    The least number such that the sum of the natural numbers smaller than n exceeds 4 is 4
    The least number such that the sum of the natural numbers smaller than n exceeds 5 is 4
    The least number such that the sum of the natural numbers smaller than n exceeds 6 is 5
    The least number such that the sum of the natural numbers smaller than n exceeds 7 is 5
    The least number such that the sum of the natural numbers smaller than n exceeds 8 is 5
    The least number such that the sum of the natural numbers smaller than n exceeds 9 is 5

UPDATE: I did solve the quadratic and came up with the following which agrees with the simpler approach.

public static int sumBeyond2(int k) {
if (k < 0) { //do not take squareroots of negatives
    return 1;
}
double x = -1.0 / 2 + Math.sqrt(1 + 8 * k) / 2; //from solving quadratic inequality n(n+1)/2.0 > k
if (Math.abs(Math.round(x) - x) < 0.0000001) { //special case, it is an integer, so ceil won't reliably add 1
    return 1 + 1 + (int) Math.round(x);
}
return 1 + (int) Math.ceil(x); //adding 1 because of wording, integers less than, ceil because needs to exceed k
}
Jeremy Kahan
  • 3,796
  • 1
  • 10
  • 23