|
1 | 1 | /**
|
2 | 2 | * @param {*[]} permutationOptions
|
| 3 | + * @param {number} permutationLength |
3 | 4 | * @return {*[]}
|
4 | 5 | */
|
5 |
| -export default function permutateWithRepetitions(permutationOptions) { |
6 |
| - // There is no permutations for empty array. |
7 |
| - if (!permutationOptions || permutationOptions.length === 0) { |
8 |
| - return []; |
| 6 | +export default function permutateWithRepetitions( |
| 7 | + permutationOptions, |
| 8 | + permutationLength = permutationOptions.length, |
| 9 | +) { |
| 10 | + if (permutationLength === 1) { |
| 11 | + return permutationOptions.map(permutationOption => [permutationOption]); |
9 | 12 | }
|
10 | 13 |
|
11 |
| - // There is only one permutation for the 1-element array. |
12 |
| - if (permutationOptions.length === 1) { |
13 |
| - return [permutationOptions]; |
14 |
| - } |
15 |
| - |
16 |
| - // Let's create initial set of permutations. |
17 |
| - let previousPermutations = permutationOptions.map(option => [option]); |
18 |
| - let currentPermutations = []; |
19 |
| - let permutationSize = 1; |
20 |
| - |
21 |
| - // While the size of each permutation is less then or equal to options length... |
22 |
| - while (permutationSize < permutationOptions.length) { |
23 |
| - // Reset all current permutations. |
24 |
| - currentPermutations = []; |
| 14 | + // Init permutations array. |
| 15 | + const permutations = []; |
25 | 16 |
|
26 |
| - for (let permIndex = 0; permIndex < previousPermutations.length; permIndex += 1) { |
27 |
| - for (let optionIndex = 0; optionIndex < permutationOptions.length; optionIndex += 1) { |
28 |
| - let currentPermutation = previousPermutations[permIndex]; |
29 |
| - currentPermutation = currentPermutation.concat([permutationOptions[optionIndex]]); |
30 |
| - currentPermutations.push(currentPermutation); |
31 |
| - } |
32 |
| - } |
| 17 | + // Go through all options and join it to the smaller permutations. |
| 18 | + permutationOptions.forEach((currentOption) => { |
| 19 | + const smallerPermutations = permutateWithRepetitions( |
| 20 | + permutationOptions, |
| 21 | + permutationLength - 1, |
| 22 | + ); |
33 | 23 |
|
34 |
| - // Make current permutations to be the previous ones. |
35 |
| - previousPermutations = currentPermutations.slice(0); |
36 |
| - |
37 |
| - // Increase permutation size counter. |
38 |
| - permutationSize += 1; |
39 |
| - } |
| 24 | + smallerPermutations.forEach((smallerPermutation) => { |
| 25 | + permutations.push([currentOption].concat(smallerPermutation)); |
| 26 | + }); |
| 27 | + }); |
40 | 28 |
|
41 |
| - return currentPermutations; |
| 29 | + return permutations; |
42 | 30 | }
|
0 commit comments