Given the powerset of 1, 2, 3
I get 8 subsets: []
, [1]
, [2]
, [2,1]
, [3]
, [3,1]
, [3,2]
, [3,2,1]
. I would like to then generate the subsets of this new set which have exactly 1 of the original set.
The number of subsets in the powerset of my powerset is 256, but there are only 8 which only contain 1 each of "1", "2" and "3", these are:
[
[
[1,2,3]
],
[
[2,3],[1]
],
[
[2],[1,3]
],
[
[3],[1,2]
],
[
[3],[2],[1]
],
[
[],[2],[1,3]
],
[
[],[3],[1,2]
],
[
[],[3],[2],[1]
]
]
Is there a way that I can get that final set without generating the second powerset with 256 subsets? I am looking for a way which can scale up to where the first set of 3 can have 10+ elements, so it isn't efficient to calculate the second powerset. Note that I don't actually require the cases where there is an empty array. My ideal answer would include only the first 5 elements. I may have pushed myself down the wrong rabbit hole by focusing on powersets. It solved my problems for n=7 but doesn't scale up to n=14.
This is the function that I currently have, but it falls over when there are 5 items in the array. I am likely approaching this from the wrong direction entirely.
function getPowerset(arr) {
return (function ps(list) {
if (list.length === 0) {
return [
[]
];
}
const head = list.pop();
const tail = ps(list);
return [...tail, ...tail.map((e) => [head, ...e])];
})([...arr]).filter(x => x.length);
}
function getCombinationsOfSet(arr) {
const subsets = getPowerset(arr);
const subsetsOfSubsets = getPowerset(subsets);
return subsetsOfSubsets.filter((subset) => {
const flattened = subset.flat();
if (flattened.length !== arr.length) {
return false;
}
let tempArr = [...arr];
for (let part of flattened) {
const index = tempArr.indexOf(part);
if (index === -1) {
return false;
}
tempArr.splice(index, 1);
}
return true;
})
}
console.time('time-taken');
console.log(getCombinationsOfSet([1, 2, 3]));
console.timeEnd('time-taken');