I am trying to find all the partitions of the elements of an array, but with an important variation:
Each value of the second array needs to be spread out over the values of the first. So all values of the second array are always used.
Given these two arrays:
left = [A, B];
right = [1, 2, 3];
I expect a collection of the following results:
A = [1, 2, 3]
B = []
A = [1, 2]
B = [3]
A = [1, 3]
B = [2]
A = [2, 3]
B = [1]
A = [1]
B = [2, 3]
A = [2]
B = [1, 3]
A = [3]
B = [1, 2]
A = []
B = [1, 2, 3]
Edit:
So just to be clear. This needs to scale for both arrays.
Given arrays:
left = [A, B, C, D]
right = [1, 2, 3, 4, 5, 6]
Some of the (many, many possible) results would be:
A = [2, 5]
B = [1]
C = []
D = [3, 4, 6]
A = [6]
B = []
C = [1, 2, 3, 4, 5]
D = []
etc. etc. etc.
Edit: This version avoids possible problems with len = Math.pow(left.length, right.length)
and problems with length over 36 (cnr!).
combine(['A', 'B'], [1, 2, 3])
all possible rows are 2^3 = 8. In this example, the distribution is binary, but it changes the base with more parameters ofleft
.
distribution included in set
i c A B
----------------------------------------
0 0 0 0 { 1, 2, 3 } { }
1 0 0 1 { 1, 2 } { 3 }
2 0 1 0 { 1, 3 } { 2 }
3 0 1 1 { 1 } { 2, 3 }
4 1 0 0 { 2, 3 } { 1 }
5 1 0 1 { 2 } { 1, 3 }
6 1 1 0 { 3 } { 1, 2 }
7 1 1 1 { } { 1, 2, 3 }
The distribution
i = 3
of0 1 1
evaluates as:
- Take the first
0
and take it as index of leftleft[0] = A
and move the place value of 0 of rightright[0] = 1
to set A.- Take the second
1
and take it as index of leftleft[1] = B
and move the place value of 1 of rightright[1] = 2
to set B.- Take the third
1
and take it as index of leftleft[1] = B
and move the place value of 2 of rightright[2] = 3
to set B.
combine(['A', 'B', 'C'], [1, 2])
all possible rows are 3^2 = 9.
distribution included in set
i c A B C
----------------------------------------
0 0 0 { 1, 2 } { } { }
1 0 1 { 1 } { 2 } { }
2 0 2 { 1 } { } { 2 }
3 1 0 { 2 } { 1 } { }
4 1 1 { } { 1, 2 } { }
5 1 2 { } { 1 } { 2 }
6 2 0 { 2 } { } { 1 }
7 2 1 { } { 2 } { 1 }
8 2 2 { } { } { 1, 2 }
function combine(left, right) {
function carry() {
return c.reduceRight(function (r, _, i, o) {
return r && !(o[i] = (o[i] + 1) % left.length);
}, 1);
}
var c = Array.apply(null, { length: right.length }).map(function () { return 0; }),
result = [];
do {
result.push(c.reduce(function (r, a, i) {
r[left[a]].push(right[i]);
return r;
}, left.reduce(function (r, a) {
r[a] = [];
return r;
}, {})));
} while (!carry());
return result;
}
document.getElementById('out').innerHTML =
"combine(['A', 'B'], [1, 2, 3]) = " + JSON.stringify(combine(['A', 'B'], [1, 2, 3]), null, 4) + '\n'+
"combine(['A', 'B', 'C'], [1, 2] = " + JSON.stringify(combine(['A', 'B', 'C'], [1, 2]), null, 4) +'\n'+
"combine(['A', 'B', 'C'], [1, 2, 3] = " + JSON.stringify(combine(['A', 'B', 'C'], [1, 2, 3]), null, 4) +'\n'+
"combine(['A', 'B', 'C', 'D'], [1, 2, 3, 4, 5, 6]) = " + JSON.stringify(combine(['A', 'B', 'C', 'D'], [1, 2, 3, 4, 5, 6]), null, 4);
<pre id="out"></pre>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With