Suppose we have the elements 0 and 1, which can occour more than once, something like 00 00 11
, 00 00 11 11
or 01 11
(split into groups of 2 for better readability).
I've already a function to generate all unique permutations:
class UniqueElement {
constructor(value, occurrences) {
this.value = value;
this.occurrences = occurrences;
}
}
function permUnique(elements) {
let set = new Set(elements);
let listunique = Array.from(set).map((i) => new UniqueElement(i, elements.filter((el) => el === i).length));
let u = elements.length;
return permUniqueHelper(listunique, "0".repeat(u).split("").map((i) => parseInt(i)), u - 1);
}
function* permUniqueHelper(listunique, result_list, d) {
if (d < 0) {
yield [...result_list];
} else {
for (const i of listunique) {
if (i.occurrences > 0) {
result_list[d] = i.value;
i.occurrences--;
for (const g of permUniqueHelper(listunique, result_list, d - 1)) yield g;
i.occurrences++;
}
}
}
}
// call like:
// permUnique([0,0,1,1])
console.log(Array.from(permUnique([0,0,1,1])).join('\n'));
Translated into JavaScript from here: https://stackoverflow.com/a/6285203/10362619
Now my intention is to use these generated permutations as indices for other objects. These are then used in code, where the order of these objects doesn't matter:
10 10
01 01
are the same in the end for example, or
01 20 12
02 10 21
10 21 02
12 01 20
...
for a base with 0
, 1
and 2
starting from 00 11 22
.
They are considered the same, because equal numbers are in the same position. Just switch two numbers (e.g. 0 with 1) and you'll get the other.
Again, all these examples are just split into groups of two for better readability. 00 11 22
means the same as 001122
, where each digit is a single element in the input array.
Is the fastest way to filter the elements afterwards after the permutations have been created or can this criteria be implemented in the function?
Edit: It is no requirement that it is a generator function that permutes the array
Edit 2: To make things even more clear: The first example I gave has the pattern abab
where a
can be either 0
or 1
and b
is the opposite. The second example follows the pattern abcabc
where a
, b
and c
can all be either 0
, 1
or 2
(but not the same).