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>