2

Working through a codewars challenge (Simple Fun #237: Suffix Sums), and while I'm passing all the tests it's giving me a time-out error. The challenge is to make a new array from a given one, where each index of the new array is the summation of that same index in the original to the end of the original array.

For an array 1, 2, 3, -6, the output should be 0, -1, -3, -6.

b[0]= 1 + 2 + 3 - 6 = 0  
b[1]=     2 + 3 - 6 = -1  
b[2]=         3 - 6 = -3  
b[3]=           - 6 = -6  

My code is this

function suffixSums(a) {
 var res=[]
 for(i=0;i<a.length;i++){
  var newarray=a.slice([i])
   res.push(newarray.reduce(function(acc, val){ return acc + val },0))
  }
  return res
}

Any clue what's up? I'm just learning still obviously, optimization is a whole new world for me

1
  • Hint: start at the end. Commented May 4, 2017 at 16:32

4 Answers 4

1

You could use the successor of an item and add the actual value while iterating from the end.

function suffixSums(a) {
    var i = a.length - 1;
    while (i--) {
        a[i] += a[i + 1];
    }
    return a;
}

console.log(suffixSums([1, 2, 3, -6]));

Sign up to request clarification or add additional context in comments.

Comments

0

You are wasting time because you calculate the sum of each items from scratch, you can start from the end of the array and accumulate the sum as you go:

function suffixSums(a) {
    var res = [],
        sum = 0;                              // sum of items from end to the current index (initialized with 0)
    for(var i = a.length - 1; i >= 0; i--) {  // loop from the end
       sum += a[i];                           // add the current number to sum
       res[i] = sum;                          // add the sum to the result array at index i (this line could be changed to: res.unshift(sum);)
    }
    return res;
}

console.log(suffixSums([1, 2, 3, -6]));

4 Comments

Awesome! Thanks for the commentary, that helps a lot. Default thinking is definitely left to right, didn't occur to me to switch it
@skdfsdfa You can do it left-to-right as well, you just have to substract the whole sum from every element
@Bergi left-to-right is undoable unless you already got the sum, in which case you'll have to loop the array twice.
@ibrahimmahrir single-pass or double-pass doesn't make a difference for algorithmic complexity :-)
0

If you don't mind changing the original array (Codewars doesn't mind):

function suffixSums(a) {
 for(var i = a.length - 2; i > -1; i--)
   a[i] += a[i+1];
 return a;
}

Comments

0

I would do this job like;

var arr = [1, 2, 3, -6],
    res = arr.reduceRight((r,n) => r[0] === void 0 ? [n] : [n+r[0]].concat(r),[]);
console.log(res);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.