UPDATE: I totally underestimated the magnitude of the problem. It's impossible to compute, at least in 2018 and the foreseeable future!
Given
SET = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
And
SUBSET_SIZES = [3, 2, 2]
I want to find all possible grouping/subset combinations of SET
, as determined by SUBSET_SIZES
, while using up all of the items in the original set.
The result for the above input would look like this:
[['a', 'b', 'c'], ['d', 'e'], ['f', 'g']],
[['a', 'b', 'c'], ['d', 'f'], ['e', 'g']],
[['a', 'b', 'c'], ['d', 'g'], ['e', 'f']],
[['a', 'b', 'c'], ['e', 'f'], ['d', 'g']],
[['a', 'b', 'c'], ['e', 'g'], ['d', 'f']],
[['a', 'b', 'c'], ['f', 'g'], ['d', 'e']],
[['a', 'b', 'd'], ['c', 'e'], ['f', 'g']],
[['a', 'b', 'd'], ['c', 'f'], ['e', 'g']],
[['a', 'b', 'd'], ['c', 'g'], ['e', 'f']],
[['a', 'b', 'd'], ['e', 'f'], ['c', 'g']],
... and 200 more ...
My actual data set will be larger (~ 50 items) and the subset sizes will vary between 4 to 6 items each, so I'm looking for a fairly efficient way to find the combinations. However, I'm okay with it taking 2-3 minutes to complete with larger datasets.
I'd like to implement that in JavaScript, so if you already know of a JavaScript code that can do the job, that'd be amazing. If it's ES6 generator code, even better! I'm running out of Googling power.
Below is a code snippet with a couple of Jasmine tests:
function getPossibleGroupCombinations() {
return [];
}
describe('getPossibleGroupCombinations', () => {
it('works with a tiny set', () => {
const possibleCombos = getPossibleGroupCombinations(['a', 'b', 'c'], [2, 1]);
expect(possibleCombos).toEqual([
[['a', 'b'], ['c']],
[['a', 'c'], ['b']],
[['b', 'c'], ['a']],
]);
});
it('works with a big set', () => {
const possibleCombos = getPossibleGroupCombinations(
['a', 'b', 'c', 'd', 'e', 'f', 'g'],
[3, 2, 2]
);
expect(possibleCombos).toEqual([
[['a', 'b', 'c'], ['d', 'e'], ['f', 'g']],
[['a', 'b', 'c'], ['d', 'f'], ['e', 'g']],
[['a', 'b', 'c'], ['d', 'g'], ['e', 'f']],
[['a', 'b', 'c'], ['e', 'f'], ['d', 'g']],
[['a', 'b', 'c'], ['e', 'g'], ['d', 'f']],
[['a', 'b', 'c'], ['f', 'g'], ['d', 'e']],
[['a', 'b', 'd'], ['c', 'e'], ['f', 'g']],
[['a', 'b', 'd'], ['c', 'f'], ['e', 'g']],
[['a', 'b', 'd'], ['c', 'g'], ['e', 'f']],
[['a', 'b', 'd'], ['e', 'f'], ['c', 'g']],
[['a', 'b', 'd'], ['e', 'g'], ['c', 'f']],
[['a', 'b', 'd'], ['f', 'g'], ['c', 'e']],
[['a', 'b', 'e'], ['c', 'd'], ['f', 'g']],
[['a', 'b', 'e'], ['c', 'f'], ['d', 'g']],
[['a', 'b', 'e'], ['c', 'g'], ['d', 'f']],
[['a', 'b', 'e'], ['d', 'f'], ['c', 'g']],
[['a', 'b', 'e'], ['d', 'g'], ['c', 'f']],
[['a', 'b', 'e'], ['f', 'g'], ['c', 'd']],
[['a', 'b', 'f'], ['c', 'd'], ['e', 'g']],
[['a', 'b', 'f'], ['c', 'e'], ['d', 'g']],
[['a', 'b', 'f'], ['c', 'g'], ['d', 'e']],
[['a', 'b', 'f'], ['d', 'e'], ['c', 'g']],
[['a', 'b', 'f'], ['d', 'g'], ['c', 'e']],
[['a', 'b', 'f'], ['e', 'g'], ['c', 'd']],
[['a', 'b', 'g'], ['c', 'd'], ['e', 'f']],
[['a', 'b', 'g'], ['c', 'e'], ['d', 'f']],
[['a', 'b', 'g'], ['c', 'f'], ['d', 'e']],
[['a', 'b', 'g'], ['d', 'e'], ['c', 'f']],
[['a', 'b', 'g'], ['d', 'f'], ['c', 'e']],
[['a', 'b', 'g'], ['e', 'f'], ['c', 'd']],
[['a', 'c', 'd'], ['b', 'e'], ['f', 'g']],
[['a', 'c', 'd'], ['b', 'f'], ['e', 'g']],
[['a', 'c', 'd'], ['b', 'g'], ['e', 'f']],
[['a', 'c', 'd'], ['e', 'f'], ['b', 'g']],
[['a', 'c', 'd'], ['e', 'g'], ['b', 'f']],
[['a', 'c', 'd'], ['f', 'g'], ['b', 'e']],
[['a', 'c', 'e'], ['b', 'd'], ['f', 'g']],
[['a', 'c', 'e'], ['b', 'f'], ['d', 'g']],
[['a', 'c', 'e'], ['b', 'g'], ['d', 'f']],
[['a', 'c', 'e'], ['d', 'f'], ['b', 'g']],
[['a', 'c', 'e'], ['d', 'g'], ['b', 'f']],
[['a', 'c', 'e'], ['f', 'g'], ['b', 'd']],
[['a', 'c', 'f'], ['b', 'd'], ['e', 'g']],
[['a', 'c', 'f'], ['b', 'e'], ['d', 'g']],
[['a', 'c', 'f'], ['b', 'g'], ['d', 'e']],
[['a', 'c', 'f'], ['d', 'e'], ['b', 'g']],
[['a', 'c', 'f'], ['d', 'g'], ['b', 'e']],
[['a', 'c', 'f'], ['e', 'g'], ['b', 'd']],
[['a', 'c', 'g'], ['b', 'd'], ['e', 'f']],
[['a', 'c', 'g'], ['b', 'e'], ['d', 'f']],
[['a', 'c', 'g'], ['b', 'f'], ['d', 'e']],
[['a', 'c', 'g'], ['d', 'e'], ['b', 'f']],
[['a', 'c', 'g'], ['d', 'f'], ['b', 'e']],
[['a', 'c', 'g'], ['e', 'f'], ['b', 'd']],
[['a', 'd', 'e'], ['b', 'c'], ['f', 'g']],
[['a', 'd', 'e'], ['b', 'f'], ['c', 'g']],
[['a', 'd', 'e'], ['b', 'g'], ['c', 'f']],
[['a', 'd', 'e'], ['c', 'f'], ['b', 'g']],
[['a', 'd', 'e'], ['c', 'g'], ['b', 'f']],
[['a', 'd', 'e'], ['f', 'g'], ['b', 'c']],
[['a', 'd', 'f'], ['b', 'c'], ['e', 'g']],
[['a', 'd', 'f'], ['b', 'e'], ['c', 'g']],
[['a', 'd', 'f'], ['b', 'g'], ['c', 'e']],
[['a', 'd', 'f'], ['c', 'e'], ['b', 'g']],
[['a', 'd', 'f'], ['c', 'g'], ['b', 'e']],
[['a', 'd', 'f'], ['e', 'g'], ['b', 'c']],
[['a', 'd', 'g'], ['b', 'c'], ['e', 'f']],
[['a', 'd', 'g'], ['b', 'e'], ['c', 'f']],
[['a', 'd', 'g'], ['b', 'f'], ['c', 'e']],
[['a', 'd', 'g'], ['c', 'e'], ['b', 'f']],
[['a', 'd', 'g'], ['c', 'f'], ['b', 'e']],
[['a', 'd', 'g'], ['e', 'f'], ['b', 'c']],
[['a', 'e', 'f'], ['b', 'c'], ['d', 'g']],
[['a', 'e', 'f'], ['b', 'd'], ['c', 'g']],
[['a', 'e', 'f'], ['b', 'g'], ['c', 'd']],
[['a', 'e', 'f'], ['c', 'd'], ['b', 'g']],
[['a', 'e', 'f'], ['c', 'g'], ['b', 'd']],
[['a', 'e', 'f'], ['d', 'g'], ['b', 'c']],
[['a', 'e', 'g'], ['b', 'c'], ['d', 'f']],
[['a', 'e', 'g'], ['b', 'd'], ['c', 'f']],
[['a', 'e', 'g'], ['b', 'f'], ['c', 'd']],
[['a', 'e', 'g'], ['c', 'd'], ['b', 'f']],
[['a', 'e', 'g'], ['c', 'f'], ['b', 'd']],
[['a', 'e', 'g'], ['d', 'f'], ['b', 'c']],
[['a', 'f', 'g'], ['b', 'c'], ['d', 'e']],
[['a', 'f', 'g'], ['b', 'd'], ['c', 'e']],
[['a', 'f', 'g'], ['b', 'e'], ['c', 'd']],
[['a', 'f', 'g'], ['c', 'd'], ['b', 'e']],
[['a', 'f', 'g'], ['c', 'e'], ['b', 'd']],
[['a', 'f', 'g'], ['d', 'e'], ['b', 'c']],
[['b', 'c', 'd'], ['a', 'e'], ['f', 'g']],
[['b', 'c', 'd'], ['a', 'f'], ['e', 'g']],
[['b', 'c', 'd'], ['a', 'g'], ['e', 'f']],
[['b', 'c', 'd'], ['e', 'f'], ['a', 'g']],
[['b', 'c', 'd'], ['e', 'g'], ['a', 'f']],
[['b', 'c', 'd'], ['f', 'g'], ['a', 'e']],
[['b', 'c', 'e'], ['a', 'd'], ['f', 'g']],
[['b', 'c', 'e'], ['a', 'f'], ['d', 'g']],
[['b', 'c', 'e'], ['a', 'g'], ['d', 'f']],
[['b', 'c', 'e'], ['d', 'f'], ['a', 'g']],
[['b', 'c', 'e'], ['d', 'g'], ['a', 'f']],
[['b', 'c', 'e'], ['f', 'g'], ['a', 'd']],
[['b', 'c', 'f'], ['a', 'd'], ['e', 'g']],
[['b', 'c', 'f'], ['a', 'e'], ['d', 'g']],
[['b', 'c', 'f'], ['a', 'g'], ['d', 'e']],
[['b', 'c', 'f'], ['d', 'e'], ['a', 'g']],
[['b', 'c', 'f'], ['d', 'g'], ['a', 'e']],
[['b', 'c', 'f'], ['e', 'g'], ['a', 'd']],
[['b', 'c', 'g'], ['a', 'd'], ['e', 'f']],
[['b', 'c', 'g'], ['a', 'e'], ['d', 'f']],
[['b', 'c', 'g'], ['a', 'f'], ['d', 'e']],
[['b', 'c', 'g'], ['d', 'e'], ['a', 'f']],
[['b', 'c', 'g'], ['d', 'f'], ['a', 'e']],
[['b', 'c', 'g'], ['e', 'f'], ['a', 'd']],
[['b', 'd', 'e'], ['a', 'c'], ['f', 'g']],
[['b', 'd', 'e'], ['a', 'f'], ['c', 'g']],
[['b', 'd', 'e'], ['a', 'g'], ['c', 'f']],
[['b', 'd', 'e'], ['c', 'f'], ['a', 'g']],
[['b', 'd', 'e'], ['c', 'g'], ['a', 'f']],
[['b', 'd', 'e'], ['f', 'g'], ['a', 'c']],
[['b', 'd', 'f'], ['a', 'c'], ['e', 'g']],
[['b', 'd', 'f'], ['a', 'e'], ['c', 'g']],
[['b', 'd', 'f'], ['a', 'g'], ['c', 'e']],
[['b', 'd', 'f'], ['c', 'e'], ['a', 'g']],
[['b', 'd', 'f'], ['c', 'g'], ['a', 'e']],
[['b', 'd', 'f'], ['e', 'g'], ['a', 'c']],
[['b', 'd', 'g'], ['a', 'c'], ['e', 'f']],
[['b', 'd', 'g'], ['a', 'e'], ['c', 'f']],
[['b', 'd', 'g'], ['a', 'f'], ['c', 'e']],
[['b', 'd', 'g'], ['c', 'e'], ['a', 'f']],
[['b', 'd', 'g'], ['c', 'f'], ['a', 'e']],
[['b', 'd', 'g'], ['e', 'f'], ['a', 'c']],
[['b', 'e', 'f'], ['a', 'c'], ['d', 'g']],
[['b', 'e', 'f'], ['a', 'd'], ['c', 'g']],
[['b', 'e', 'f'], ['a', 'g'], ['c', 'd']],
[['b', 'e', 'f'], ['c', 'd'], ['a', 'g']],
[['b', 'e', 'f'], ['c', 'g'], ['a', 'd']],
[['b', 'e', 'f'], ['d', 'g'], ['a', 'c']],
[['b', 'e', 'g'], ['a', 'c'], ['d', 'f']],
[['b', 'e', 'g'], ['a', 'd'], ['c', 'f']],
[['b', 'e', 'g'], ['a', 'f'], ['c', 'd']],
[['b', 'e', 'g'], ['c', 'd'], ['a', 'f']],
[['b', 'e', 'g'], ['c', 'f'], ['a', 'd']],
[['b', 'e', 'g'], ['d', 'f'], ['a', 'c']],
[['b', 'f', 'g'], ['a', 'c'], ['d', 'e']],
[['b', 'f', 'g'], ['a', 'd'], ['c', 'e']],
[['b', 'f', 'g'], ['a', 'e'], ['c', 'd']],
[['b', 'f', 'g'], ['c', 'd'], ['a', 'e']],
[['b', 'f', 'g'], ['c', 'e'], ['a', 'd']],
[['b', 'f', 'g'], ['d', 'e'], ['a', 'c']],
[['c', 'd', 'e'], ['a', 'b'], ['f', 'g']],
[['c', 'd', 'e'], ['a', 'f'], ['b', 'g']],
[['c', 'd', 'e'], ['a', 'g'], ['b', 'f']],
[['c', 'd', 'e'], ['b', 'f'], ['a', 'g']],
[['c', 'd', 'e'], ['b', 'g'], ['a', 'f']],
[['c', 'd', 'e'], ['f', 'g'], ['a', 'b']],
[['c', 'd', 'f'], ['a', 'b'], ['e', 'g']],
[['c', 'd', 'f'], ['a', 'e'], ['b', 'g']],
[['c', 'd', 'f'], ['a', 'g'], ['b', 'e']],
[['c', 'd', 'f'], ['b', 'e'], ['a', 'g']],
[['c', 'd', 'f'], ['b', 'g'], ['a', 'e']],
[['c', 'd', 'f'], ['e', 'g'], ['a', 'b']],
[['c', 'd', 'g'], ['a', 'b'], ['e', 'f']],
[['c', 'd', 'g'], ['a', 'e'], ['b', 'f']],
[['c', 'd', 'g'], ['a', 'f'], ['b', 'e']],
[['c', 'd', 'g'], ['b', 'e'], ['a', 'f']],
[['c', 'd', 'g'], ['b', 'f'], ['a', 'e']],
[['c', 'd', 'g'], ['e', 'f'], ['a', 'b']],
[['c', 'e', 'f'], ['a', 'b'], ['d', 'g']],
[['c', 'e', 'f'], ['a', 'd'], ['b', 'g']],
[['c', 'e', 'f'], ['a', 'g'], ['b', 'd']],
[['c', 'e', 'f'], ['b', 'd'], ['a', 'g']],
[['c', 'e', 'f'], ['b', 'g'], ['a', 'd']],
[['c', 'e', 'f'], ['d', 'g'], ['a', 'b']],
[['c', 'e', 'g'], ['a', 'b'], ['d', 'f']],
[['c', 'e', 'g'], ['a', 'd'], ['b', 'f']],
[['c', 'e', 'g'], ['a', 'f'], ['b', 'd']],
[['c', 'e', 'g'], ['b', 'd'], ['a', 'f']],
[['c', 'e', 'g'], ['b', 'f'], ['a', 'd']],
[['c', 'e', 'g'], ['d', 'f'], ['a', 'b']],
[['c', 'f', 'g'], ['a', 'b'], ['d', 'e']],
[['c', 'f', 'g'], ['a', 'd'], ['b', 'e']],
[['c', 'f', 'g'], ['a', 'e'], ['b', 'd']],
[['c', 'f', 'g'], ['b', 'd'], ['a', 'e']],
[['c', 'f', 'g'], ['b', 'e'], ['a', 'd']],
[['c', 'f', 'g'], ['d', 'e'], ['a', 'b']],
[['d', 'e', 'f'], ['a', 'b'], ['c', 'g']],
[['d', 'e', 'f'], ['a', 'c'], ['b', 'g']],
[['d', 'e', 'f'], ['a', 'g'], ['b', 'c']],
[['d', 'e', 'f'], ['b', 'c'], ['a', 'g']],
[['d', 'e', 'f'], ['b', 'g'], ['a', 'c']],
[['d', 'e', 'f'], ['c', 'g'], ['a', 'b']],
[['d', 'e', 'g'], ['a', 'b'], ['c', 'f']],
[['d', 'e', 'g'], ['a', 'c'], ['b', 'f']],
[['d', 'e', 'g'], ['a', 'f'], ['b', 'c']],
[['d', 'e', 'g'], ['b', 'c'], ['a', 'f']],
[['d', 'e', 'g'], ['b', 'f'], ['a', 'c']],
[['d', 'e', 'g'], ['c', 'f'], ['a', 'b']],
[['d', 'f', 'g'], ['a', 'b'], ['c', 'e']],
[['d', 'f', 'g'], ['a', 'c'], ['b', 'e']],
[['d', 'f', 'g'], ['a', 'e'], ['b', 'c']],
[['d', 'f', 'g'], ['b', 'c'], ['a', 'e']],
[['d', 'f', 'g'], ['b', 'e'], ['a', 'c']],
[['d', 'f', 'g'], ['c', 'e'], ['a', 'b']],
[['e', 'f', 'g'], ['a', 'b'], ['c', 'd']],
[['e', 'f', 'g'], ['a', 'c'], ['b', 'd']],
[['e', 'f', 'g'], ['a', 'd'], ['b', 'c']],
[['e', 'f', 'g'], ['b', 'c'], ['a', 'd']],
[['e', 'f', 'g'], ['b', 'd'], ['a', 'c']],
[['e', 'f', 'g'], ['c', 'd'], ['a', 'b']],
]);
});
});
// load jasmine htmlReporter
(function() {
var env = jasmine.getEnv();
env.addReporter(new jasmine.HtmlReporter());
env.execute();
}());
<link href="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine.js"></script>
<script src="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine-html.js"></script>