I am unable to figure out how to write a function that will calculate all possible sums of of the elements of an array, with a max of 4 elements per addition.
Given<
jsFiddle Demo
You can use a permutation subset recursive algorithm to find the set of all of the sums and also their combinations.
var x = [1, 32, 921, 9213, 97, 23, 97, 81, 965, 82, 965, 823];
var sums = [];
var sets = [];
function SubSets(read, queued){
if( read.length == 4 || (read.length <= 4 && queued.length == 0) ){
if( read.length > 0 ){
var total = read.reduce(function(a,b){return a+b;},0);
if(sums.indexOf(total)==-1){
sums.push(total);
sets.push(read.slice().sort());
}
}
}else{
SubSets(read.concat(queued[0]),queued.slice(1));
SubSets(read,queued.slice(1));
}
}
SubSets([],x);
console.log(sums.sort(function(a,b){return a-b;}));
//log sums without sort to have them line up to sets or modify previous structure
console.log(sets);
There is a function to generate combinations of k members of a population of n here: https://gist.github.com/axelpale/3118596.
I won't reproduce the function here. You can combine it with another function to sum the combinations generated from an input array, e.g.
// Add combinations of k members of set
function getComboSums(set, k) {
return k_combinations(arr, n).map(function(a){
var sum=0;
a.forEach(function(v){sum += v})
return sum;
});
}
This can be combined with another function to get all combinations from 2 to 4 and concatenate them all together. Note that the total number of combinations in a set of 12 members is 781.
// Add all combinations from kStart to kEnd of set
function getComboSumRange(set, kStart, kEnd) {
var result = [];
for (var i=kStart; i <= kEnd; i++) {
result = result.concat(getComboSums(set, i));
}
return result;
}
Then given:
var arr = [1, 32, 921, 9213, 97, 23, 97, 81, 965, 82, 965, 823];
console.log(getComboSumRange(arr, 2, 4)) // length is 781
The length of 781 agrees with the calculated number of terms based on the formula for finding combinations of k in n:
n! / (k!(n - k)!)
and summing for k = 2 -> 4.
The result looks like:
[33, 922, 9214, 98, 24, 98 ... 2834, 1951, 2835];
You can see the terms start with:
arr[0] + arr[1], arr[0] + arr[2]], ...
and end with:
... arr[7] + arr[9] + arr[10] + arr[11], arr[8] + arr[9] + arr[10] + arr[11]