Search code examples
javascriptarraysrecursionsumreduce

Array Reduce Sum Using Recursion


Given an array of length n, consolidate the sum created by adding index pairs until there's only a single index.

EXAMPLES:

[1, 2, 3, 4, 5] => 48

Explanation:

  • The next array would be [3, 5, 7, 9] because [1+2, 2+3, 3+4, 4+5]
  • The next array would be [8, 12, 16] because [3+5, 5+7, 7+9]
  • The next array would be [20, 28] because [8+12, 12+16]
  • The final answer would be [48] because [20+28] and there are not enough operands to add

This is the solution I came up with but I feel like there's a simpler way to achieve the same solution. I'm trying to understand recursion but I need some explanation on why when we call our stacks, we do it from the (n - 1) or from the (n + 1) to reach our base cases and how do we know which one to use? I don't understand why we're using those passing arguments when we are returning our helper function.

function reduceSum(input) {
  function simplify(input, index) {
    if (index === 1) {
      return input[0];
    }

    if (index === 0) {
      return 0;
    }

    for (let i = 0; i < input.length; i++) {
      input[i] += input[i + 1];
    }

    return simplify(input, index - 1);
  }

  return simplify(input, input.length);
}


console.log(reduceSum([1, 2, 3, 4]) == 20)
console.log(reduceSum([5]) == 5)
console.log(reduceSum([]) == 0)
console.log(reduceSum([1, 3, 5]) == 12)
console.log(reduceSum([-5, 5]) == 0)
console.log(reduceSum([-5, 5, -5, 5]) == 0)
console.log(reduceSum([-5, 5, 5, -5]) == 20)


Solution

  • I'm not sure the following is a genuinely simpler way to achieve the solution as it does basically the same thing (although it does not modify the original array), but perhaps there's something useful here:

    function reduceSum(input) {
      if(input.length <= 1)
        return input[0] || 0;
      
      return reduceSum(
        input.reduce(
          (acc, val, i, { [i + 1]: next }) =>
            typeof next !== 'undefined' ? [ ...acc, val + next ] : acc,
          []
        )
      );
    }
    
    
    console.log(reduceSum([1, 2, 3, 4]) == 20)
    console.log(reduceSum([5]) == 5)
    console.log(reduceSum([]) == 0)
    console.log(reduceSum([1, 3, 5]) == 12)
    console.log(reduceSum([-5, 5]) == 0)
    console.log(reduceSum([-5, 5, -5, 5]) == 0)
    console.log(reduceSum([-5, 5, 5, -5]) == 20)

    The next variable is populated using object destructuring on the array argument passed to the reduce callback function. It will be undefined when the reduce method processes the last element of the array, this last element gets skipped; this means that each time we run reduceSum the array gets shorter by one element (as per your original).