output each combination of an array of numbers with javascript - stack overflow

4
Take the 2-minute tour × DaveKingsnorth 65 2 7 4 Answers I have several numbers in an array var numArr = [1, 3, 5, 9]; I want to cycle through that array and multiply every unique 3 number combination as follows: 1 * 3 * 5 = 1 * 3 * 9 = 1 * 5 * 9 = 3 * 5 * 9 = Then return an array of all the calculations var ansArr = [15,27,45,135]; Anyone have an elegant solution? Thanks in advance. javascript combinations edited Oct 30 '10 at 23:35 asked Oct 30 '10 at 23:12 3 In the title you ask for permutations, but in the body you mention combinations. Which is it? (I'm guessing combinations, since multiplication is commutative.) – Marcelo Cantos Oct 30 '10 at 23:20 1 @DaveKingsnorth Note: You have strings in your array, not numbers. – Šime Vidas Oct 30 '10 at 23:25 Sorry it's combinations – DaveKingsnorth Oct 30 '10 at 23:25 @Sime Vidas - That was a mistake, they should be numbers not strings – DaveKingsnorth Oct 30 '10 at 23:27 1 @DaveKingsnorth Are the numbers in the array distinct? – Šime Vidas Oct 30 '10 at 23:30 show 4 more comments A general-purpose algorithm for generating combinations is as follows: function combinations(numArr, choose, callback) { var n = numArr.length; var c = []; var inner = function(start, choose_) { if (choose_ == 0) { callback(c); } else { for (var i = start; i <= n - choose_; ++i) { c.push(numArr[i]); inner(i + 1, choose_ - 1); c.pop(); } } } inner(0, choose); } In your case, you might call it like so: function product(arr) { Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required. Output each combination of an array of numbers with javascript sign up log in tour help careers 2.0 Output each combination of an array of numbers with javascri... http://stackoverflow.com/questions/4061080/output-each-com... 1 of 4 09/04/14 1:27 PM

Upload: rudra-mukharjee

Post on 26-May-2017

217 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Output Each Combination of an Array of Numbers With Javascript - Stack Overflow

Take the 2-minute tour ×

DaveKingsnorth65 2 7

4 Answers

I have several numbers in an array

var numArr = [1, 3, 5, 9];

I want to cycle through that array and multiply every unique 3 number combination as follows:

1 * 3 * 5 = 1 * 3 * 9 = 1 * 5 * 9 = 3 * 5 * 9 =

Then return an array of all the calculations

var ansArr = [15,27,45,135];

Anyone have an elegant solution? Thanks in advance.

javascript combinations

edited Oct 30 '10 at 23:35 asked Oct 30 '10 at 23:12

3 In the title you ask for permutations, but in the body you mention combinations. Which is it? (I'm guessingcombinations, since multiplication is commutative.) – Marcelo Cantos Oct 30 '10 at 23:20

1 @DaveKingsnorth Note: You have strings in your array, not numbers. – Šime Vidas Oct 30 '10 at 23:25

Sorry it's combinations – DaveKingsnorth Oct 30 '10 at 23:25

@Sime Vidas - That was a mistake, they should be numbers not strings – DaveKingsnorth Oct 30 '10 at23:27

1 @DaveKingsnorth Are the numbers in the array distinct? – Šime Vidas Oct 30 '10 at 23:30

show 4 more comments

A general-purpose algorithm for generating combinations is as follows:

function combinations(numArr, choose, callback) { var n = numArr.length; var c = []; var inner = function(start, choose_) { if (choose_ == 0) { callback(c); } else { for (var i = start; i <= n - choose_; ++i) { c.push(numArr[i]); inner(i + 1, choose_ - 1); c.pop(); } } } inner(0, choose);}

In your case, you might call it like so:

function product(arr) {

Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, noregistration required.

Output each combination of an array of numbers with javascript

sign up log in tour help careers 2.0

Output each combination of an array of numbers with javascri... http://stackoverflow.com/questions/4061080/output-each-com...

1 of 4 09/04/14 1:27 PM

Page 2: Output Each Combination of an Array of Numbers With Javascript - Stack Overflow

Marcelo Cantos88.9k 10 157 224

p = 1; for (var i in arr) { p *= arr[i]; } return p;}

var ansArr = [];

combinations( [1, 3, 5, 7, 9, 11], 3, function output(arr) { ansArr.push(product(arr)); });

document.write(ansArr);

...which, for the given input, yields this:

15,21,27,33,35,45,55,63,77,99,105,135,165,189,231,297,315,385,495,693

edited Oct 31 '10 at 0:03 answered Oct 30 '10 at 23:52

This is awesome. Thanks a lot! – DaveKingsnorth Oct 31 '10 at 0:13

I think this should work:

var a = [1, 3, 5, 9];var l = a.length;var r = [];for (var i = 0; i < l; ++i) { for (var j = i + 1; j < l; ++j) { for (var k = j + 1; k < l; ++k) { r.push(a[i] * a[j] * a[k]); } }}

Edit

Just for my own edification, I figured out a generic solution that uses loops instead of recursion. It's obviousdownside is that it's longer thus slower to load or to read. On the other hand (at least on Firefox on mymachine) it runs about twice as fast as the recursive version. However, I'd only recommend it if you're findingcombinations for large sets, or finding combinations many times on the same page. Anyway, in caseanybody's interested, here's what I came up with.

function combos(superset, size) { var result = []; if (superset.length < size) {return result;} var done = false; var current_combo, distance_back, new_last_index; var indexes = []; var indexes_last = size - 1; var superset_last = superset.length - 1;

// initialize indexes to start with leftmost combo for (var i = 0; i < size; ++i) { indexes[i] = i; }

while (!done) { current_combo = []; for (i = 0; i < size; ++i) { current_combo.push(superset[indexes[i]]); } result.push(current_combo); if (indexes[indexes_last] == superset_last) { done = true; for (i = indexes_last - 1; i > -1 ; --i) { distance_back = indexes_last - i; new_last_index = indexes[indexes_last - distance_back] + distance_back + if (new_last_index <= superset_last) {

Output each combination of an array of numbers with javascri... http://stackoverflow.com/questions/4061080/output-each-com...

2 of 4 09/04/14 1:27 PM

Page 3: Output Each Combination of an Array of Numbers With Javascript - Stack Overflow

Sid_M359 1 4

indexes[indexes_last] = new_last_index; done = false; break; } } if (!done) { ++indexes[indexes_last - distance_back]; --distance_back; for (; distance_back; --distance_back) { indexes[indexes_last - distance_back] = indexes[indexes_last - distance_back } } } else {++indexes[indexes_last]} } return result;}

function products(sets) { var result = []; var len = sets.length; var product; for (var i = 0; i < len; ++i) { product = 1; inner_len = sets[i].length; for (var j = 0; j < inner_len; ++j) { product *= sets[i][j]; } result.push(product); } return result;}

console.log(products(combos([1, 3, 5, 7, 9, 11], 3)));

edited Nov 1 '10 at 4:02 answered Oct 30 '10 at 23:43

Perfect! Thanks a lot – DaveKingsnorth Oct 30 '10 at 23:51

If I wanted to get all 2 number combinations or 5 number combinations (if I had a longer array), is there asolution where I can specify that value as a variable (I'm talking about specifying the length of the combinations).– DaveKingsnorth Oct 30 '10 at 23:59

@DaveKingsnorth if you want to vary that, then my solution's too specific. See Marcelo's more generic solution.– Sid_M Oct 31 '10 at 0:12

Your solution actually answers my original question but Marcelo's is exactly what I was after. Thanks for yourinput. – DaveKingsnorth Oct 31 '10 at 0:15

A recursive function to do this when you need to select k numbers among n numbers. Have not tested. Findif there is any bug and rectify it :-)

var result = [];

foo(arr, 0, 1, k, n); // initial call

function foo(arr, s, mul, k, n) { if (k == 1) { result.push(mul); return; }

var i; for (i=s; i<=n-k; i++) { foo(arr, i+1, mul*arr[i], k-1, n-i-1); }}

This is a recursive function.

First parameter is array arr .1.

Second parameter is integer s . Each call calculates values for part of the array starting from index s .Recursively I am increasing s and so array for each call is recursively becoming smaller.

2.

Third parameter is the value that is being calculated recursively and is being passed in the recursivecall. When k becomes 1, it gets added in the result array.

3.

k in the size of combination desired. It decreases recursively and when becomes 1, output appendedin result array.

4.

Output each combination of an array of numbers with javascri... http://stackoverflow.com/questions/4061080/output-each-com...

3 of 4 09/04/14 1:27 PM

Page 4: Output Each Combination of an Array of Numbers With Javascript - Stack Overflow

BBog2,051 2 13 41

Niraj Nawanit965 1 5 10

Mikola5,262 14 26

n is size of array arr . Actually n = arr.length5.

edited Nov 27 '12 at 15:30 answered Oct 31 '10 at 0:35

@ Niraj - Can you explain what each of the parameters are please? – DaveKingsnorth Oct 31 '10 at 0:57

This is a recursive function. 1) First parameter is array arr. 2) Second parameter is integer s. Each callcalculates values for part of the array starting from index s. Recursively I am increasing s and so array for eachcall is recursively becoming smaller. 3) Third parameter is the value that is being calculated recursively and isbeing passed in the recursive call. When k becomes 1, it gets added in the result array. 4) k in the size ofcombination desired. It decreases recursively and when becomes 1, output appended in result array. 5) n is sizeof array arr. Actually n = arr.length – Niraj Nawanit Oct 31 '10 at 7:31

That's what I thought but I'm still making a mistake somewhere. I'm calling the function like this: var arr = [2, 1, 4,1, 6]; foo(arr, 0, 1, 4, 5); and outputting it like this: document.write(result); What am I doing wrong? – DaveKingsnorth Nov 2 '10 at 0:23

Using node, you can do this pretty easily using a library. First install bit-twiddle using npm:

npm install bit-twiddle

Then you can use it in your code like this:

//Assume n is the size of the set and k is the size of the combinationvar nextCombination = require("bit-twiddle").nextCombinationfor(var x=(1<<(k+1))-1; x<1<<n; x=nextCombination(x)) { console.log(x.toString(2))}

The variable x is a bit-vector where bit i is set if the i th element is contained in the combination.

answered Mar 15 '13 at 20:15

Not the answer you're looking for? Browse other questions tagged javascript

combinations or ask your own question.

Output each combination of an array of numbers with javascri... http://stackoverflow.com/questions/4061080/output-each-com...

4 of 4 09/04/14 1:27 PM