|
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