|
1 | 1 | /**
|
2 |
| - * @param {*[]} combinationOptions |
3 |
| - * @param {number} combinationLength |
| 2 | + * @param {*[]} comboOptions |
| 3 | + * @param {number} comboLength |
4 | 4 | * @return {*[]}
|
5 | 5 | */
|
6 |
| - |
7 |
| -export default function combineWithRepetitions(combinationOptions, combinationLength) { |
8 |
| - // If combination length equal to 0 then return empty combination. |
9 |
| - if (combinationLength === 0) { |
10 |
| - return [[]]; |
11 |
| - } |
12 |
| - |
13 |
| - // If combination options are empty then return "no-combinations" array. |
14 |
| - if (combinationOptions.length === 0) { |
15 |
| - return []; |
| 6 | +export default function combineWithRepetitions(comboOptions, comboLength) { |
| 7 | + if (comboLength === 1) { |
| 8 | + return comboOptions.map(comboOption => [comboOption]); |
16 | 9 | }
|
17 | 10 |
|
18 | 11 | // Init combinations array.
|
19 | 12 | const combos = [];
|
20 | 13 |
|
21 |
| - // Find all shorter combinations and attach head to each of those. |
22 |
| - const headCombo = [combinationOptions[0]]; |
23 |
| - const shorterCombos = combineWithRepetitions(combinationOptions, combinationLength - 1); |
| 14 | + // Eliminate characters one by one and concatenate them to |
| 15 | + // combinations of smaller lengths. |
| 16 | + for (let optionIndex = 0; optionIndex < comboOptions.length; optionIndex += 1) { |
| 17 | + const currentOption = comboOptions[optionIndex]; |
24 | 18 |
|
25 |
| - for (let combinationIndex = 0; combinationIndex < shorterCombos.length; combinationIndex += 1) { |
26 |
| - const combo = headCombo.concat(shorterCombos[combinationIndex]); |
27 |
| - combos.push(combo); |
28 |
| - } |
| 19 | + const smallerCombos = combineWithRepetitions( |
| 20 | + comboOptions.slice(optionIndex), |
| 21 | + comboLength - 1, |
| 22 | + ); |
29 | 23 |
|
30 |
| - // Let's shift head to the right and calculate all the rest combinations. |
31 |
| - const combinationsWithoutHead = combineWithRepetitions( |
32 |
| - combinationOptions.slice(1), |
33 |
| - combinationLength, |
34 |
| - ); |
| 24 | + smallerCombos.forEach((smallerCombo) => { |
| 25 | + combos.push([currentOption].concat(smallerCombo)); |
| 26 | + }); |
| 27 | + } |
35 | 28 |
|
36 |
| - // Join all combinations and return them. |
37 |
| - return combos.concat(combinationsWithoutHead); |
| 29 | + return combos; |
38 | 30 | }
|
0 commit comments