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 = 3of0 1 1evaluates as:
- Take the first
 0and take it as index of leftleft[0] = Aand move the place value of 0 of rightright[0] = 1to set A.- Take the second
 1and take it as index of leftleft[1] = Band move the place value of 1 of rightright[1] = 2to set B.- Take the third
 1and take it as index of leftleft[1] = Band move the place value of 2 of rightright[2] = 3to 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