From 65f08db5deb8737ee0a9cf89518c9a99c1fccfb0 Mon Sep 17 00:00:00 2001 From: Oleksii Trekhleb Date: Thu, 28 Jun 2018 14:05:58 +0300 Subject: [PATCH] Simplify combineWithRepetitions function. --- .../combinations/combineWithRepetitions.js | 44 ++++++++----------- .../combinations/combineWithoutRepetitions.js | 11 ++--- 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/src/algorithms/sets/combinations/combineWithRepetitions.js b/src/algorithms/sets/combinations/combineWithRepetitions.js index 0d2ef3c1..a95d2857 100644 --- a/src/algorithms/sets/combinations/combineWithRepetitions.js +++ b/src/algorithms/sets/combinations/combineWithRepetitions.js @@ -1,38 +1,30 @@ /** - * @param {*[]} combinationOptions - * @param {number} combinationLength + * @param {*[]} comboOptions + * @param {number} comboLength * @return {*[]} */ - -export default function combineWithRepetitions(combinationOptions, combinationLength) { - // If combination length equal to 0 then return empty combination. - if (combinationLength === 0) { - return [[]]; - } - - // If combination options are empty then return "no-combinations" array. - if (combinationOptions.length === 0) { - return []; +export default function combineWithRepetitions(comboOptions, comboLength) { + if (comboLength === 1) { + return comboOptions.map(comboOption => [comboOption]); } // Init combinations array. const combos = []; - // Find all shorter combinations and attach head to each of those. - const headCombo = [combinationOptions[0]]; - const shorterCombos = combineWithRepetitions(combinationOptions, combinationLength - 1); + // Eliminate characters one by one and concatenate them to + // combinations of smaller lengths. + for (let optionIndex = 0; optionIndex < comboOptions.length; optionIndex += 1) { + const currentOption = comboOptions[optionIndex]; - for (let combinationIndex = 0; combinationIndex < shorterCombos.length; combinationIndex += 1) { - const combo = headCombo.concat(shorterCombos[combinationIndex]); - combos.push(combo); + const smallerCombos = combineWithRepetitions( + comboOptions.slice(optionIndex), + comboLength - 1, + ); + + smallerCombos.forEach((smallerCombo) => { + combos.push([currentOption].concat(smallerCombo)); + }); } - // Let's shift head to the right and calculate all the rest combinations. - const combinationsWithoutHead = combineWithRepetitions( - combinationOptions.slice(1), - combinationLength, - ); - - // Join all combinations and return them. - return combos.concat(combinationsWithoutHead); + return combos; } diff --git a/src/algorithms/sets/combinations/combineWithoutRepetitions.js b/src/algorithms/sets/combinations/combineWithoutRepetitions.js index a6f50ec0..8f712b51 100644 --- a/src/algorithms/sets/combinations/combineWithoutRepetitions.js +++ b/src/algorithms/sets/combinations/combineWithoutRepetitions.js @@ -8,20 +8,21 @@ export default function combineWithoutRepetitions(comboOptions, comboLength) { return comboOptions.map(comboOption => [comboOption]); } + // Init combinations array. const combos = []; // Eliminate characters one by one and concatenate them to - // combinations of smaller lengths.s - for (let letterIndex = 0; letterIndex <= (comboOptions.length - comboLength); letterIndex += 1) { - const currentLetter = comboOptions[letterIndex]; + // combinations of smaller lengths. + for (let optionIndex = 0; optionIndex <= (comboOptions.length - comboLength); optionIndex += 1) { + const currentOption = comboOptions[optionIndex]; const smallerCombos = combineWithoutRepetitions( - comboOptions.slice(letterIndex + 1), + comboOptions.slice(optionIndex + 1), comboLength - 1, ); smallerCombos.forEach((smallerCombo) => { - combos.push([currentLetter].concat(smallerCombo)); + combos.push([currentOption].concat(smallerCombo)); }); }