I am trying to write a function that returns the number x. y number of times. The function should be able to take in multiple 2d arrays. There will be only 2 elements per input array.
So for example: function([4,3][2,2][12,5])
//output should be exactly: 444, 22, 1212121212
I have solved most of the problem but I am stuck when x is a 2 digit number.
would appreciate some help in solving this. I must return the solution as a string with a comma (' ,') that separates the different arrays.
Here is my code as of now:
function repeatnumber(data){
var result = " ";
for (var i = 0; i < data.length; i++){
if (Array.isArray(data[i])){
var x = data[i][0]
var y = data[i][1]
for(var j = 1; j <= y; j++){
result = result + x;
}
}
}
var number = result
var answer = number.match(/(\d)\1*/g)
return console.log(answer);
}
repeatnumber([[10, 2][11,1]])// DOESN'T WORK!! output must be: 1010,11
repeatnumber([[1, 2], [2, 3]]) //works
repeatnumber([[1, 4], [3, 6], [9, 2]]) //works
You could check if you got a nested array and map new values and join later all arrays with comma.
function repeatnumber(array) {
return (Array.isArray(array[0]) ? array : [array])
.map(([value, length]) => Array.from({ length }, _ => value).join(''))
.join(', ');
}
console.log(repeatnumber([42, 7]));
console.log(repeatnumber([[10, 2], [11,1]]));
console.log(repeatnumber([[1, 2], [2, 3]]));
console.log(repeatnumber([[1, 4], [3, 6], [9, 2]]));
If you are using es6 this could be the simplest.
let repeatnumber = (inputArr) => {
return inputArr.map((inp) => `${inp[0]}`.repeat(inp[1]));
}
Here's one of the solution.
function repeatNumber(data) {
var results = '';
data.forEach(function(arr) {
for(var i = 0; i< arr[1]; i++) results += arr[0].toString();
results += ',';
})
return results.substring(0, results.length - 1);
}
console.log(repeatNumber([[10, 2], [11,1]]));
console.log(repeatNumber([[1, 2], [2, 3]]));
console.log(repeatNumber([[1, 4], [3, 6], [9, 2]]));
As you've noticed, regex isn't the best option. You're making the question a lot more difficult than it needs to be. You can just make an array of each of those strings and then join them together. Also, more descriptive variable names will go a long way for you.
let data = [[10,2], [11,1]]
function repeatNumber(data) {
let resultArray = []
for (let i=0; i < data.length; i++) {
let num = data[i][0]
let times = data[i][1]
let newString = ""
for (let j=0; j < times; j++) {
newString += num
}
resultArray.push(newString)
}
return resultArray.join(", ")
}
console.log(repeatNumber(data))
If you're ok with a code golf solution, this will accomplish the same task:
data.map(([num, times]) => Array(times).fill(num).join("")).join(", ")
try this :
function repeatnumber(data) {
var result = "";
for (var i = 0; i < data.length; i++)
{
if (Array.isArray(data[i]))
{
var x = data[i][0]
var y = data[i][1]
for(var j = 1; j <= y; j++)
{
{
result = result + x;
}
}
}
if(i != data.length - 1)
result += " ";
}
var number = result
var split = number.split(" ");
//var answer = number.match(/(\d)\1*/g)
return console.log(split);
}
repeatnumber([[10, 2][11,1]]) should be repeatnumber([[10, 2],[11,1]]);
ES6 Solution
const repeat = (arr) => {
arr.map( v => {
const str = new Array(v[1] + 1).join(v[0]);
console.log(str); // save this in array or wherever u want.
})
};
repeat([[1, 4], [3, 6], [9, 2]])
You are missing a comma between two arrays, make it
repeatnumber([[10, 2],[11,1]])
Also, your regex won't work properly when you are adding two digit number, change your logic as
function repeatnumber(data)
{
var answer = [];
for (var i = 0; i < data.length; i++)
{
if (Array.isArray(data[i]))
{
var x = data[i][0]
var y = data[i][1]
result = "";
for(var j = 1; j <= y; j++)
{
result = result + x;
}
answer.push(result)
}
}
return answer;
}
Demo
function repeatnumber(data) {
var answer = [];
for (var i = 0; i < data.length; i++) {
if (Array.isArray(data[i])) {
var x = data[i][0]
var y = data[i][1]
result = "";
for (var j = 1; j <= y; j++) {
result = result + x;
}
answer.push(result)
}
}
return answer;
}
console.log(repeatnumber([
[10, 2],
[11, 1]
])) ;
console.log(repeatnumber([
[1, 2],
[2, 3]
])) ;
console.log(repeatnumber([
[1, 4],
[3, 6],
[9, 2]
])) ;
Edit
Or a more concise method using fill and reduce
function repeatnumber(data)
{
return data.map( s => Array( s[1] ).fill( "" ).reduce( (a,c) => a + s[ 0 ], "" ) )
}
Or using fill and join
function repeatnumber(data)
{
return data.map( s => Array( s[1] + 1 ).fill( "" ).join( s[ 0 ] ) )
}
Small code that works,
// iterate > create array and join with char > join parent array with comma
function repeatnumber(data){
if(!data || data.length < 1) return [];
return data.map(arr => Array(arr[1] + 1).join(arr[0])).join(',');
}
A better approach, thanks to Ariz
function repeatnumber(data) {
if (!data || data.length < 1) return [];
return data.map((arr) => `${arr[0]}`.repeat(arr[1])).join(',');
}
No creation of an extra array, so huge repetitions can be done with ease.
Single pass by nested template literals and .reduce() working hand to hand.
var a = [[10, 2], [11,1]],
b = [[1, 2], [2, 3]],
c = [[1, 4], [3, 6], [9, 2]],
f = a => a.reduce((r,[v,c],i) => `${i ? `${r},`:``}${`${v}`.repeat(c)}`,``);
console.log(f(a));
console.log(f(b));
console.log(f(c));
I want to collect all subarrays for further computation efficiently in javascript. I'm not sure this is possible, but it seems for a subarray sum kadane's formula is o(n) which is more efficient than other methods. But I'm not sure I how I can store the array at each step.
Similar to this quora question, for me the pseudo code was not enough. Thanks for the further breakdown.
another meta link
an example in action of this for [3, 3, 9, 9, 5]
[3], [9], [5], [9, 5], [9, 3], [9, 9], [3, 3],
[3, 9, 9], [3, 3, 9], [9, 9, 5], [3, 3, 9, 9],
[3, 9, 9, 5], [3, 3, 9, 9, 5]
I had done a work previously to calculate all combinations of amino acids total molecular weight. If you neglect the empty one you should have 2^n - 1 sub arrays. So there is no O(n) here. I've got two methods as binary and recursive.
function getSubArrays(arr){
var len = arr.length,
subs = Array(Math.pow(2,len)).fill();
return subs.map((_,i) => { var j = -1,
k = i,
res = [];
while (++j < len ) {
k & 1 && res.push(arr[j]);
k = k >> 1;
}
return res;
}).slice(1);
}
console.log(JSON.stringify(getSubArrays([1,2,3,4,5])));
function getSubArrays(arr){
if (arr.length === 1) return [arr];
else {
subarr = getSubArrays(arr.slice(1));
return subarr.concat(subarr.map(e => e.concat(arr[0])), [[arr[0]]]);
}
}
console.log(JSON.stringify(getSubArrays([1,2,3,4,5])));
I couldn't manage to get subarrays of an array with more than 23 items though.
Here are the performances. To be on the safe side i try with 22 items, first with recursive and then with binary route.
function getSubArrays(arr){
if (arr.length === 1) return [arr];
else {
subarr = getSubArrays(arr.slice(1));
return subarr.concat(subarr.map(e => e.concat(arr[0])), [[arr[0]]]);
}
}
var aminos = Array(22).fill().map((_,i) => i+1),
subarrs = [],
ps = 0,
pe = 0;
ps = performance.now();
subarrs = getSubArrays(aminos);
pe = performance.now();
console.log("recursive route took: " + (pe-ps) + "msec to produce " + subarrs.length + " sub arrays");
function getSubArrays(arr){
var len = arr.length,
subs = Array(Math.pow(2,len)).fill();
return subs.map((_,i) => { var j = -1,
k = i,
res = [];
while (++j < len ) {
k & 1 && res.push(arr[j]);
k = k >> 1;
}
return res;
}).slice(1);
}
var aminos = Array(22).fill().map((_,i) => i+1),
subarrs = [],
ps = 0,
pe = 0;
ps = performance.now();
subarrs = getSubArrays(aminos);
pe = performance.now();
console.log("binary route took: " + (pe-ps) + "msec to produce " + subarrs.length + " sub arrays");
This is fairly simple to do: https://jsfiddle.net/j1LuvxLq/
All you do is iterate possible lenghts and starting points and just print out the subsets. Complexity is O(n²) where n is the length of the original array. No way to improve it thought because that's the order of how many subsets there are.
var set = [3, 3, 9, 9, 5].join('')
var set_length = set.length
var subsets = []
for (var length_of_subset = 1; length_of_subset <= set_length; length_of_subset++) {
for (var start_of_subset = 0; start_of_subset <= set_length - length_of_subset; start_of_subset++) {
var current_subset = set.substring(start_of_subset, start_of_subset + length_of_subset)
if(subsets.indexOf(current_subset) == -1) {
subsets.push(current_subset.split(''))
}
}
}
// print the subsets out
for (s in subsets) {
$('body').append(subsets[s].join(', ') + '<br>')
}
Alternative, possibly nicer solution would be to use dynamic programming. Start with 3 and either remove last element or add next element. Check it out here: https://jsfiddle.net/p82fcs4m/
var set = [3, 3, 9, 9, 5].join('')
var subsets = []
take(set[0], set.substring(1))
function take(chosen, left) {
if(subsets.indexOf(chosen) != -1) {
return
}
subsets.push(chosen)
if (chosen.length > 1) {
take(chosen.substring(1), left)
}
if (left.length > 0) {
take(chosen.concat(left[0]), left.substring(1))
}
}
$('body').append(subsets.join('<br>'))
Try this:
function getSubArrays(arr) {
const subArrays = [];
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length - i; j++) {
const subArray = arr.slice(i, j + i + 1);
subArrays.push(subArray);
}
}
}
Still O(n²) tho
I believe using Array.slice is the most clean way to do it, isn't it?
function getSubArrays(arr) {
const subArrays = [];
for (var i = 0; i < arr.length; i++) {
for (var j = i; j < arr.length; j++) {
subArrays.push(arr.slice(i, j + 1));
}
}
return subArrays;
}
var a = [1,3,6,10,-1];
function combinations(array, n) {
}
combinations(a, 9) // should return...
[[1], [3], [6], [-1], [1,3], [1,6], [1,-1], [3,6], [3,-1], [6, -1], [10, -1], [1,3,-1], [3,6,-1], [1,6,-1], [1,3,6,-1]]
maybe i'm missing some correct answers but you get the idea. Really dying to know how to solve this!
I would say the problem here is to take the power set of an array, and filter it down to only the elements whose sum is greater than a certain number.
The power set of a set is the set of all subsets of that set. (Say that five times fast and you'll be a mathematician)
For example, the power set of [1] is [[], [1]] and the power set of [1, 2] is [[], [1], [2], [1, 2]].
First I would define a powerSet function like this:
var powerSet = function (arr) {
// the power set of [] is [[]]
if(arr.length === 0) {
return [[]];
}
// remove and remember the last element of the array
var lastElement = arr.pop();
// take the powerset of the rest of the array
var restPowerset = powerSet(arr);
// for each set in the power set of arr minus its last element,
// include that set in the powerset of arr both with and without
// the last element of arr
var powerset = [];
for(var i = 0; i < restPowerset.length; i++) {
var set = restPowerset[i];
// without last element
powerset.push(set);
// with last element
set = set.slice(); // create a new array that's a copy of set
set.push(lastElement);
powerset.push(set);
}
return powerset;
};
Then I would define a function that takes the power set of the array and only includes elements whose sum is less than or equal to some amount:
var subsetsLessThan = function (arr, number) {
// all subsets of arr
var powerset = powerSet(arr);
// subsets summing less than or equal to number
var subsets = [];
for(var i = 0; i < powerset.length; i++) {
var subset = powerset[i];
var sum = 0;
for(var j = 0; j < subset.length; j++) {
sum += subset[j];
}
if(sum <= number) {
subsets.push(subset);
}
}
return subsets;
};
This might not be fast on large arrays, but it works well for small ones.
It looks like it gives the right answer for console.log(subsetsLessThan([1,3,6,10,-1], 9));
edit: a little more about the power set function as implemented here
The only subset of [] is [], so the power set of [] is a set containing only []. That would be [[]].
The initial if statement in the powerSet function immediately returns [[]] if you pass in [].
var powerSet = function (arr) {
if(arr.length === 0) {
return [[]];
}
If you pass in a set with at least one element, the powerSet function begins by removing the last element. For example, if you call powerSet on [1, 2], the variable lastElement will be set to 2 and arr will be set to [1].
var lastElement = arr.pop();
Then the powerSet function recursively calls itself to get the power set of the "rest" of the list. If you had passed in [1, 2], then restPowerset is assigned to powerSet([1]) which is [[], [1]].
var restPowerset = powerSet(arr);
We define a variable that's going to hold the power set of what was passed in, here [1, 2]
var powerset = [];
We loop through every set in restPowerset.
for(var i = 0; i < restPowerset.length; i++) {
var set = restPowerset[i];
Any subset of [1] is also a subset of [1, 2] so we add it to the list. That is, [] and [1] are both subsets of [1, 2].
powerset.push(set);
If you add the element 2 to any subset of [1], that is also a subset of [1, 2], so we add it to the list. Both [2] and [1, 2] are subsets of [1, 2].
set = set.slice(); // copy the array
set.push(lastElement); // add the element
powerset.push(set);
That's all. At this point, the variable powerset is [[], [2], [1], [1, 2]]. Return it!
}
return powerset;
};
Brute force O(N*2N) solution, where N = a.length < 31.
This uses the index i as a bit field to filter the elements of a in each iteration into a sublist.
var a = [1,3,6,10,-1];
function combinations(array, n) {
var lists = [], M = 1<<array.length;
for( var i = 1 ; i < M ; ++i ) {
var sublist = array.filter(function(c,k){return i>>k & 1});
if( sublist.reduce(function(p,c){return p+c},0) <= n )
lists.push(sublist);
}
return lists;
}
console.log(JSON.stringify(combinations(a,9)));
[[1],[3],[1,3],[6],[1,6],[3,6],[-1],[1,-1],[3,-1],[1,3,-1],[6,-1],[1,6,-1],[3,6,-1],[1,3,6,-1],[10,-1]]
Similar to Matt's answer, but uses Array.filter() and Array.reduce() to pack a punch. The variable, mask is incremented from 1 to 32-1 in this example (because array length is 5 and count = 1 << 5, which is 32). The array is filtered for each mask increment, producing a new array or permutation where only certain values are included.
A value is included in the permutation if the mask shifted right by the value's index is odd. Think binary here, because either a value is supposed to be in the permutation or it isn't (0 or 1) and since the mask will go through all possible numbers, all of the possible permutations are covered directly in the number when expressed as binary:
index: 4,3,2,1,0
mask: 0 0 0 0 1 (grab index 0, [1])
mask: 0 0 0 1 0 (grab index 1, [3])
mask: 0 0 0 1 1 (grab index 0 and 1, [1,3])
mask: 1 1 0 0 0 (grab index 3 and 4, [10,-1])
var a = [1,3,6,10,-1];
function combinations(array, n) {
var mask, len = array.length, count = 1 << len, permutations = [];
var indexVisible = function(v, i) { return ((mask >> i) & 1) == 1 }
var sum = function(a, b) { return a + b }
for (mask = 1; mask < count; ++mask) {
permutations.push(array.filter(indexVisible))
}
return permutations.filter(function(p) { return p.reduce(sum) <= n })
}
console.log(JSON.stringify(combinations(a, 9)));
The function, indexVisible() is used to filter the original array and return a permutation that matches the mask.
The function, sum() is used to reduce each permutation to the sum of its values, and if that sum is less than or equal to n then it is included in the final result and returned from combinations()
Here are the permutations:
[[1],[3],[1,3],[6],[1,6],[3,6],[1,3,6],[10],[1,10],[3,10],[1,3,10],[6,10],[1,6,10],[3,6,10],[1,3,6,10],[-1],[1,-1],[3,-1],[1,3,-1],[6,-1],[1,6,-1],[3,6,-1],[1,3,6,-1],[10,-1],[1,10,-1],[3,10,-1],[1,3,10,-1],[6,10,-1],[1,6,10,-1],[3,6,10,-1],[1,3,6,10,-1]]
Here are the results:
[[1],[3],[1,3],[6],[1,6],[3,6],[-1],[1,-1],[3,-1],[1,3,-1],[6,-1],[1,6,-1],[3,6,-1],[1,3,6,-1],[10,-1]]
You can see how all of this works and play with different combinations in this JSFiddle.
The following code will give you all sub-arrays summing up to 9 or less..
function getSubArrays(arr,n){
var len = arr.length,
subs = Array(Math.pow(2,len)).fill();
return subs.map((_,i) => { var j = -1,
k = i,
res = [];
while (++j < len ) {
k & 1 && res.push(arr[j]);
k = k >> 1;
}
return res;
}).slice(1)
.filter(a => a.reduce((p,c) => p+c) <= n);
}
var arr = [1,3,6,10,-1],
result = getSubArrays(arr,9);
console.log(JSON.stringify(result));
edit: giving credit where due.. borrowed the bulk of this logic from this answer
var combinations = function(a,m) {
var gc = function(a) {
var fn = function(n, src, got, all) {
if (n == 0) {
if (got.length > 0) {
all[all.length] = got;
}
return;
}
for (var j = 0; j < src.length; j++) {
fn(n - 1, src.slice(j + 1), got.concat([src[j]]), all);
}
return;
}
var all = [];
for (var i = 0; i < a.length; i++) {
fn(i, a, [], all);
}
all.push(a);
return all;
}
var c = gc(a);
return c.filter(function(e) {
var n = e.length;
var sum = 0;
while(n--)
sum += parseFloat(e[n]) || 0;
return sum<=m;
},m);
}
var a = [1,3,6,10,-1];
combinations(a,9);
output
[[1], [3], [6], [-1], [1, 3], [1, 6], [1, -1], [3, 6], [3, -1], [6, -1], [10, -1], [1, 3, -1], [1, 6, -1], [3, 6, -1], [1, 3, 6, -1]]
It looked like to much fun not to play, here's what I have.
Javascript
function kCombs(set, k) {
var setLength = set.length,
combs = [],
i = 0,
tailLength,
head,
tail,
j,
t,
u;
if (k > 0 && k <= setLength) {
if (k === setLength) {
combs.push(set);
} else if (k === 1) {
while (i < setLength) {
combs.push([set[i]]);
i += 1;
}
} else {
u = k - 1;
setLength = setLength - k + 1;
while (i < setLength) {
t = i + 1;
head = set.slice(i, t);
tail = kCombs(set.slice(t), u);
j = 0;
tailLength = tail.length;
while (j < tailLength) {
combs.push(head.concat(tail[j]));
j += 1;
}
i = t;
}
}
}
return combs;
}
function combinations(array, n) {
var arrayLength = array.length,
combs = [],
combsLength,
results = [],
temp = 0,
current,
currentLength,
i,
j,
k = 1;
while (k <= arrayLength) {
i = 0;
current = kCombs(array, k);
currentLength = current.length;
while (i < currentLength) {
combs.push(current[i]);
i += 1;
}
k += 1;
}
i = 0;
combsLength = combs.length;
while (i < combsLength) {
j = 0;
current = combs[i];
currentLength = current.length;
while (j < currentLength) {
temp += current[j];
j += 1;
}
if (temp <= n) {
results.push(current);
}
temp = 0;
i += 1;
}
return results;
}
var a = [1, 3, 6, 10, -1];
console.log(JSON.stringify(combinations(a, 9)));
Output
[[1],[3],[6],[-1],[1,3],[1,6],[1,-1],[3,6],[3,-1],[6,-1],[10,-1],[1,3,-1],[1,6,-1],[3,6,-1],[1,3,6,-1]]
On jsFiddle
And a jsPerf of all these, although #jcarpenter solutions gives an ambiguity.
On a modern browser you could squeeze more out of this solution using for intead of while as they are highly optimised for for. And assign by index rather than push would also give you a performance boost.
It would be nice to extend the performance tests to include some more test sets, maybe if I get bored.
Brevity is very cryptic here. How about some descriptive functions?
The approach uses binary to create maps of all the possible combinations. Then the map is used to pluck items from the array. The plucked items are summed, and that's about it.
The result of combinations([1, 3, 6, 10, -1], 9) produced is: [[-1],[10,-1],[6],[6,-1],[3],[3,-1],[3,6],[3,6,-1],[1],[1,-1],[1,6],[1,6,-1],[1,3],[1,3,-1],[1,3,6,-1]].
Here is a Fiddle.
/**
* Get an array of all the possible combinations
* of x items. Combinations are represented as binary.
* #param {Number} x - example 2
* #return {String[]} - example ['00', '01', '10', '11']
*/
function getCombinationsOfXItems(x) {
var allOn = '',
numCombos = 0,
i = 0,
combos = [];
// find upper limit
while (allOn.length < x) {
allOn += 1;
}
// number of possible combinations
numCombos = parseInt(allOn, 2) + 1;
// generate the combos
while(i < numCombos) {
combos.push(pad(toBase2(i++), allOn.length));
}
return combos;
}
/**
* Pad a string with leading zeros.
* #param {String} x - example '100'
* #param {Number} length - example 6
* #return {String} - example '000100'
*/
function pad(x, length) {
while (x.length < length) {
x = 0 + x;
}
return x;
}
/**
* Get a number as a binary string.
* #param {Number} x - example 3
* #return {String} - example '11'
*/
function toBase2(x) {
return x.toString(2);
}
/**
* Given an array and a map of its items as a binary string,
* return the items identified by 1.
* #param {Array} arr - example [1,2,3]
* #param {String} binary - example '101'
* #return {Array} - example [1,3]
*/
function pluckFromArrayByBinary(arr, binary) {
var plucked = [],
i = 0,
max = binary.length;
for (; i < max; i++) {
if (binary[i] === '1') {
plucked.push(arr[i]);
}
}
return plucked;
}
/**
* Given an array, return a multi-dimensional
* array of all the combinations of its items.
* #param {Array} - example [1, 2];
* #return {Array[]} - [ [1], [1, 2], [2] ]
*/
function getCombosOfArrayItems(arr) {
var comboMaps = getCombinationsOfXItems(arr.length),
combos = [];
// remove the "all off" combo (ex: '00000')
comboMaps.shift();
for (var i = 0; i < comboMaps.length; i++) {
combos.push(pluckFromArrayByBinary(arr, comboMaps[i]));
}
return combos;
}
/**
* Return all possible combinations of numbers in an
* array whose sum is less than or equal to n
* #param {Number[]} arr
* #param {Number} x
* return {Number[]} - stringified for readability
*/
function combinations(arr, x) {
var combos = getCombosOfArrayItems(arr),
i = 0,
max = combos.length,
combo;
for (; i < max; i++) {
if (sumArray(combos[i]) > x) {
combos.splice(i, 1);
i--;
max--;
}
}
return JSON.stringify(combos);
}
/**
* Return the sum of an array of numbers.
* #param {Number[]} arr
* #return {Number}
*/
function sumArray(arr) {
var sum = 0,
i = 0,
max = arr.length;
for (; i < max; i++) {
sum += arr[i];
}
return sum;
}
console.log(combinations([1, 3, 6, 10, -1], 9));
#jcarpenter solution was so nice I just had to rework it for those that love ECMA5. This will not be as fast as the raw power of for, the modern methods have not had the length of time to be so highly optimised (and they do quite a bit more work). But the performance results do show just how good the powerSet algorithm is (and it is a reusable function). I've also filtered out the ambiguity, which slows things slightly.
Javascript
function powerSet(arr) {
var lastElement,
val;
if (!arr.length) {
val = [[]];
} else {
lastElement = arr.pop();
val = powerSet(arr).reduce(function (previous, element) {
previous.push(element);
element = element.slice();
element.push(lastElement);
previous.push(element);
return previous;
}, []);
}
return val;
}
function combinations(array, n) {
return powerSet(array).filter(function (set) {
return set.length && set.reduce(function (previous, element) {
return previous + element;
}, 0) <= n;
});
}
var a = [1, 3, 6, 10, -1];
console.log(JSON.stringify(combinations(a, 9)));
Output
[[-1],[10,-1],[6],[6,-1],[3],[3,-1],[3,6],[3,6,-1],[1],[1,-1],[1,6],[1,6,-1],[1,3],[1,3,-1],[1,3,6,-1]]
On jsFiddle
And added to the jsPerf
Try this:
var a = [1,3,6,10,-1];
function combinations(array, n) {
var arrayCopy = [],
results = [];
// duplicate the array
for (var i in array)
arrayCopy[i] = array[i];
for (var i in array)
for (var j in arrayCopy)
if ((array[i] + arrayCopy[j]) <= n)
results.push([array[i], arrayCopy[j]]);
return results;
}
console.log(combinations(a, 9));
This logged:
[1, 1], [1, 3], [1, 6], [1, -1],
[3, 1], [3, 3], [3, 6], [3, -1],
[6, 1], [6, 3], [6, -1],
[10, -1],
[-1, 1], [-1, 3], [-1, 6], [-1, 10], [-1, -1]