Skip to content

Instantly share code, notes, and snippets.

@istro
Last active December 19, 2015 14:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save istro/5973617 to your computer and use it in GitHub Desktop.
Save istro/5973617 to your computer and use it in GitHub Desktop.
The challenge: Given an array of integers, find the largest possible sum of consecutive elements of that array. Example: For array [3, -4, 8, -2, -1, 20] the output should be 25, because 8+(-2)+(-1)+20 Live version can be found on codepen - http://codepen.io/istro/pen/qEesB
// To break down the problem for myself better, I like to write some tests.
var test = function(){
// Array contains only negative integers -> result is the single largest element
if(findSum([-14, -5, -22]) != -5 && findSum([-3, -23, -1]) != -1){
alert('First test case fails.');
return false;
}
// Array contains only positive integers -> result is the sum of all elements
if(findSum([1, 2, 3]) != 6 && findSum([5, 6]) != 11){
alert('Second test case fails.');
return false;
}
// Array contains a mixture of both.
if(findSum([-1, 3, -2, -20, 4]) != 4 && findSum([3, -2, 6, 4, -6]) != 11){
alert('Third test case fails.');
return false;
}
alert('Yay! tests pass!');
return true;
};
var findSum = function(array){
// For the first test case, I have to ensure the array only has negative numbers.
// Why not sort it, non-destructively.
var arrCopy = array.slice();
arrCopy.sort(function(a, b){ return b-a });
if(arrCopy[0]<0)
return arrCopy[0];
// Sorted array comes handy for the second test case, too:
var sum = 0;
if(arrCopy[arrCopy.length-1]>0){
$.each(array, function(index, value){
sum += value;
});
return sum;
};
// Cool. For the third case, I don't care about consecutive positives or consecutive negatives -
// they're just as good as the sum of them. So I'll make sure I don't have any repetition going on.
// start the short array with first element of the input array
var shortie = [array[0]];
for(i=1; i<array.length; i++){
var shortiesLast = shortie[shortie.length-1];
// compare next element's sign (positive/negative), if they match - just add it to last element,
// if not - add as a new element
if(array[i]>0 && shortiesLast>0 || array[i]<0 && shortiesLast<0){
shortie[shortie.length-1] = shortiesLast+array[i];
}else{
shortie.push(array[i]);
}
}
// also, if my shortened array starts or ends with the negative number - i don't care about it:
if(shortie[shortie.length-1]<0)
shortie.pop();
if(shortie[0]<0)
shortie.shift();
// Cool, shortie is now an array with alternating signs. It only makes sense to include negative
// numbers in the sum if both positive numbers are larger than the one they surround,
// e.g. [2, -10, 400] shouldn't get summed up while [20, -19, 21] should.
// I can iterate over that array in bigger steps - and create sums of all
// reasonable 'chunks' of the array, like so:
var sums = [shortie[0]];
for(i=1; i<shortie.length; i+=2){
var ohSoNegative = Math.abs(shortie[i]);
if(ohSoNegative<shortie[i-1] && ohSoNegative<shortie[i+1]){
sums[sums.length-1] += (shortie[i] + shortie[i+1]);
}else{
sums.push(shortie[i+1]);
};
}
// All that's left is return the largest sum.
sums.sort(function(a, b){ return b-a });
return sums[0];
}
test();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment