skip to Main Content

I am trying to resolve this situation in js:

Given three integers i, j, k, I want to calculate this sum:

 i+(i+1)+(i+2)+...+j+(j-1)+(j-2)+...+k

if i=0, j=5, k=-1, the result should be 24
if i=5, j=9, k=6, the result should be 56.
Because i increase until is equal to j and then decrease until is equal to k.

I tryed this:

 function getSequenceSum(i, j, k) {
      let sum = 0;
      if (i <= j) {
        while (i < j) {
          i = i + 1;
          sum = sum + i;
        }
        while (j > k) {
          j = j - 1;
          sum = sum + j;
        }
      }

      return sum;
    }

console.log(getSequenceSum(0, 5, -1));
console.log(getSequenceSum(5, 9, 6));

but the output was 51, any suggestions? Thanks

3

Answers


  1. so, in reality your sum is:
    { i + (i+1)+(i+2)...(i+n) while((i+n) < j) }
    + { j + (j-1)+(j-2)...(j-m) while((j-m) >= k) }

    so your second while() should be while(j >= k), not while(j > k)

    console.log( getSequenceSum(0,5,-1)) // -> 24  
    console.log( getSequenceSum(5,9,6))  // -> 56
    
    function getSequenceSum(i, j, k)
      {
      if (i > j || j < k) return 0; 
      let sum = 0;
      while (i < j) sum += i++;
      while (j >= k) sum += j--;
      return sum;
      }
    Login or Signup to reply.
  2. Here’s an O(1) solution.

    Input: i, j, k: i < j, j > k.

    The sum from i to j is: (i+0) + (i+1) + (i+2) + … + j

    Note that j = i + (j-i).

    So this is the sum from (i+0) to (i+j-i). This sum has (j-i+1) terms, so we can rewrite it as:

    (j-i+1)*i + (1+2+3+...+(j-i))
    = (j-i+1)*i + (j-i)*(j-i+1)/2
    

    Then we need the sum from k to j-1. This is identical to the above, except we swap the i for k and the j for j-1.

    Helper method:

    f(a, b) = (b-a+1)*a + (b-a)*(b-a+1)/2
    

    Solution:

    g(i, j, k) = f(i, j) + f(k, j-1)
    

    Ruby implementation (sorry, don’t know javascript; ready as pseduocode)

    def f(a, b)
      return (b-a+1)*a + (b-a)*(b-a+1)/2
    end
    
    def g(i, j, k)
      return f(i, j) + f(k, j-1)
    end
    
    > g(0,5,-1)
    => 24
    > g(5,9,6)
    => 56
    

    Javascript code courtesy of @Jabaa

    function f(a, b) {
        return (b-a+1)*a + (b-a)*(b-a+1)/2;
    }
    
    function g(i, j, k) {
        return f(i, j) + f(k, j-1);
    }
    
    console.log(g(0,5,-1));
    console.log(g(5,9,6));
    Login or Signup to reply.
  3. Your second loop is off by one and you should first add the number, then increment/decrement it, otherwise you miss the first element of the range:

    function getSequenceSum(i, j, k) {
      let sum = 0;
      if (i <= j) {
        while (i < j) {
          sum += i;
          ++i;
        }
        while (j >= k) {
          sum += j;
          --j;
        }
      }
      return sum;
    }
    
    console.log(getSequenceSum(0, 5, -1));
    console.log(getSequenceSum(5, 9, 6));

    I would change the code to

    function getSequenceSum(i, j, k) {
      if (i > j || j < k) {
        return 0;
      }
      let sum = 0;
      while (i < j) {
        sum += i;
        ++i;
      }
      while (j >= k) {
        sum += j;
        --j;
      }
      return sum;
    }
    
    console.log(getSequenceSum(0, 5, -1));
    console.log(getSequenceSum(5, 9, 6));

    but it has different behavior. It checks the ranges with early exit.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search