From cb14892e4ee78111556b44036adeb17aeef09fa4 Mon Sep 17 00:00:00 2001 From: Oleksii Trekhleb Date: Mon, 23 Apr 2018 09:38:46 +0300 Subject: [PATCH] Add combinations. --- README.md | 6 +- .../{string => math}/combinations/README.md | 0 .../__test__/combineWithRepetitions.test.js | 2 +- .../combineWithoutRepetitions.test.js | 60 ++++++++++++++++ .../combinations/combineWithRepetitions.js | 0 .../combinations/combineWithoutRepetitions.js | 11 +-- .../{string => math}/permutations/README.md | 0 .../__test__/permutateWithRepetitions.test.js | 55 ++++++++++++++ .../permutateWithoutRepetitions.test.js | 71 +++++++++++++++++++ .../permutations/permutateWithRepetitions.js | 42 +++++++++++ .../permutateWithoutRepetitions.js | 39 ++++++++++ .../combineWithoutRepetitions.test.js | 40 ----------- .../__test__/permutateWithRepetitions.test.js | 53 -------------- .../permutateWithoutRepetitions.test.js | 69 ------------------ .../permutations/permutateWithRepetitions.js | 41 ----------- .../permutateWithoutRepetitions.js | 39 ---------- 16 files changed, 277 insertions(+), 251 deletions(-) rename src/algorithms/{string => math}/combinations/README.md (100%) rename src/algorithms/{string => math}/combinations/__test__/combineWithRepetitions.test.js (96%) create mode 100644 src/algorithms/math/combinations/__test__/combineWithoutRepetitions.test.js rename src/algorithms/{string => math}/combinations/combineWithRepetitions.js (100%) rename src/algorithms/{string => math}/combinations/combineWithoutRepetitions.js (82%) rename src/algorithms/{string => math}/permutations/README.md (100%) create mode 100644 src/algorithms/math/permutations/__test__/permutateWithRepetitions.test.js create mode 100644 src/algorithms/math/permutations/__test__/permutateWithoutRepetitions.test.js create mode 100644 src/algorithms/math/permutations/permutateWithRepetitions.js create mode 100644 src/algorithms/math/permutations/permutateWithoutRepetitions.js delete mode 100644 src/algorithms/string/combinations/__test__/combineWithoutRepetitions.test.js delete mode 100644 src/algorithms/string/permutations/__test__/permutateWithRepetitions.test.js delete mode 100644 src/algorithms/string/permutations/__test__/permutateWithoutRepetitions.test.js delete mode 100644 src/algorithms/string/permutations/permutateWithRepetitions.js delete mode 100644 src/algorithms/string/permutations/permutateWithoutRepetitions.js diff --git a/README.md b/README.md index 62650ba8..7f68441e 100644 --- a/README.md +++ b/README.md @@ -32,13 +32,13 @@ * [Fibonacci Number](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/fibonacci) * [Cartesian Product](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/cartesian-product) * [Power Set](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/power-set) - * [Primality Test](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/primality-test) (trial division) + * [Permutations](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/permutations) (with and without repetitions) + * [Combinations](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/combinations) (with and without repetitions) + * [Primality Test](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/primality-test) (trial division method) * [Euclidean Algorithm](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/euclidean-algorithm) - calculate the greatest common divisor (GCD) * [Least Common Multiple (LCM)](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/least-common-multiple) * [Fisher–Yates Shuffle](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/fisher-yates) - random permutation of a finite sequence * **String** - * [Permutations](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/string/permutations) (with and without repetitions) - * [Combinations](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/string/combinations) (with and without repetitions) * Minimum Edit distance (Levenshtein Distance) * Hamming * Huffman diff --git a/src/algorithms/string/combinations/README.md b/src/algorithms/math/combinations/README.md similarity index 100% rename from src/algorithms/string/combinations/README.md rename to src/algorithms/math/combinations/README.md diff --git a/src/algorithms/string/combinations/__test__/combineWithRepetitions.test.js b/src/algorithms/math/combinations/__test__/combineWithRepetitions.test.js similarity index 96% rename from src/algorithms/string/combinations/__test__/combineWithRepetitions.test.js rename to src/algorithms/math/combinations/__test__/combineWithRepetitions.test.js index 90c38958..25c8a20c 100644 --- a/src/algorithms/string/combinations/__test__/combineWithRepetitions.test.js +++ b/src/algorithms/math/combinations/__test__/combineWithRepetitions.test.js @@ -1,5 +1,5 @@ import combineWithRepetitions from '../combineWithRepetitions'; -import factorial from '../../../math/factorial/factorial'; +import factorial from '../../factorial/factorial'; describe('combineWithRepetitions', () => { it('should combine string with repetitions', () => { diff --git a/src/algorithms/math/combinations/__test__/combineWithoutRepetitions.test.js b/src/algorithms/math/combinations/__test__/combineWithoutRepetitions.test.js new file mode 100644 index 00000000..1c048ada --- /dev/null +++ b/src/algorithms/math/combinations/__test__/combineWithoutRepetitions.test.js @@ -0,0 +1,60 @@ +import combineWithoutRepetitions from '../combineWithoutRepetitions'; +import factorial from '../../factorial/factorial'; + +describe('combineWithoutRepetitions', () => { + it('should combine string without repetitions', () => { + expect(combineWithoutRepetitions(['A', 'B'], 3)).toEqual([]); + + expect(combineWithoutRepetitions(['A', 'B'], 1)).toEqual([ + ['A'], + ['B'], + ]); + + expect(combineWithoutRepetitions(['A'], 1)).toEqual([ + ['A'], + ]); + + expect(combineWithoutRepetitions(['A', 'B'], 2)).toEqual([ + ['A', 'B'], + ]); + + expect(combineWithoutRepetitions(['A', 'B', 'C'], 2)).toEqual([ + ['A', 'B'], + ['A', 'C'], + ['B', 'C'], + ]); + + expect(combineWithoutRepetitions(['A', 'B', 'C'], 3)).toEqual([ + ['A', 'B', 'C'], + ]); + + expect(combineWithoutRepetitions(['A', 'B', 'C', 'D'], 3)).toEqual([ + ['A', 'B', 'C'], + ['A', 'B', 'D'], + ['A', 'C', 'D'], + ['B', 'C', 'D'], + ]); + + expect(combineWithoutRepetitions(['A', 'B', 'C', 'D', 'E'], 3)).toEqual([ + ['A', 'B', 'C'], + ['A', 'B', 'D'], + ['A', 'B', 'E'], + ['A', 'C', 'D'], + ['A', 'C', 'E'], + ['A', 'D', 'E'], + ['B', 'C', 'D'], + ['B', 'C', 'E'], + ['B', 'D', 'E'], + ['C', 'D', 'E'], + ]); + + const combinationOptions = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']; + const combinationSlotsNumber = 4; + const combinations = combineWithoutRepetitions(combinationOptions, combinationSlotsNumber); + const n = combinationOptions.length; + const r = combinationSlotsNumber; + const expectedNumberOfCombinations = factorial(n) / (factorial(r) * factorial(n - r)); + + expect(combinations.length).toBe(expectedNumberOfCombinations); + }); +}); diff --git a/src/algorithms/string/combinations/combineWithRepetitions.js b/src/algorithms/math/combinations/combineWithRepetitions.js similarity index 100% rename from src/algorithms/string/combinations/combineWithRepetitions.js rename to src/algorithms/math/combinations/combineWithRepetitions.js diff --git a/src/algorithms/string/combinations/combineWithoutRepetitions.js b/src/algorithms/math/combinations/combineWithoutRepetitions.js similarity index 82% rename from src/algorithms/string/combinations/combineWithoutRepetitions.js rename to src/algorithms/math/combinations/combineWithoutRepetitions.js index c087990d..a8217fc5 100644 --- a/src/algorithms/string/combinations/combineWithoutRepetitions.js +++ b/src/algorithms/math/combinations/combineWithoutRepetitions.js @@ -38,14 +38,14 @@ */ /** - * @param {string} combinationOptions + * @param {*[]} combinationOptions * @param {number} combinationLength - * @return {string[]} + * @return {*[]} */ export default function combineWithoutRepetitions(combinationOptions, combinationLength) { // If combination length is just 1 then return combinationOptions. if (combinationLength === 1) { - return Array.from(combinationOptions); + return combinationOptions.map(option => [option]); } // Init combinations array. @@ -53,12 +53,13 @@ export default function combineWithoutRepetitions(combinationOptions, combinatio for (let i = 0; i <= (combinationOptions.length - combinationLength); i += 1) { const smallerCombinations = combineWithoutRepetitions( - combinationOptions.substr(i + 1), + combinationOptions.slice(i + 1), combinationLength - 1, ); for (let j = 0; j < smallerCombinations.length; j += 1) { - combinations.push(combinationOptions[i] + smallerCombinations[j]); + const combination = [combinationOptions[i]].concat(smallerCombinations[j]); + combinations.push(combination); } } diff --git a/src/algorithms/string/permutations/README.md b/src/algorithms/math/permutations/README.md similarity index 100% rename from src/algorithms/string/permutations/README.md rename to src/algorithms/math/permutations/README.md diff --git a/src/algorithms/math/permutations/__test__/permutateWithRepetitions.test.js b/src/algorithms/math/permutations/__test__/permutateWithRepetitions.test.js new file mode 100644 index 00000000..2984b7c9 --- /dev/null +++ b/src/algorithms/math/permutations/__test__/permutateWithRepetitions.test.js @@ -0,0 +1,55 @@ +import permutateWithRepetitions from '../permutateWithRepetitions'; + +describe('permutateWithRepetitions', () => { + it('should permutate string with repetition', () => { + const permutations0 = permutateWithRepetitions([]); + expect(permutations0).toEqual([]); + + const permutations1 = permutateWithRepetitions(['A']); + expect(permutations1).toEqual([ + ['A'], + ]); + + const permutations2 = permutateWithRepetitions(['A', 'B']); + expect(permutations2).toEqual([ + ['A', 'A'], + ['A', 'B'], + ['B', 'A'], + ['B', 'B'], + ]); + + const permutations3 = permutateWithRepetitions(['A', 'B', 'C']); + expect(permutations3).toEqual([ + ['A', 'A', 'A'], + ['A', 'A', 'B'], + ['A', 'A', 'C'], + ['A', 'B', 'A'], + ['A', 'B', 'B'], + ['A', 'B', 'C'], + ['A', 'C', 'A'], + ['A', 'C', 'B'], + ['A', 'C', 'C'], + ['B', 'A', 'A'], + ['B', 'A', 'B'], + ['B', 'A', 'C'], + ['B', 'B', 'A'], + ['B', 'B', 'B'], + ['B', 'B', 'C'], + ['B', 'C', 'A'], + ['B', 'C', 'B'], + ['B', 'C', 'C'], + ['C', 'A', 'A'], + ['C', 'A', 'B'], + ['C', 'A', 'C'], + ['C', 'B', 'A'], + ['C', 'B', 'B'], + ['C', 'B', 'C'], + ['C', 'C', 'A'], + ['C', 'C', 'B'], + ['C', 'C', 'C'], + ]); + + const permutations4 = permutateWithRepetitions(['A', 'B', 'C', 'D']); + expect(permutations4.length).toBe(4 * 4 * 4 * 4); + }); +}); diff --git a/src/algorithms/math/permutations/__test__/permutateWithoutRepetitions.test.js b/src/algorithms/math/permutations/__test__/permutateWithoutRepetitions.test.js new file mode 100644 index 00000000..3d082c90 --- /dev/null +++ b/src/algorithms/math/permutations/__test__/permutateWithoutRepetitions.test.js @@ -0,0 +1,71 @@ +import permutateWithoutRepetitions from '../permutateWithoutRepetitions'; +import factorial from '../../factorial/factorial'; + +describe('permutateWithoutRepetitions', () => { + it('should permutate string', () => { + const permutations0 = permutateWithoutRepetitions([]); + expect(permutations0).toEqual([]); + + const permutations1 = permutateWithoutRepetitions(['A']); + expect(permutations1).toEqual([ + ['A'], + ]); + + const permutations2 = permutateWithoutRepetitions(['A', 'B']); + expect(permutations2.length).toBe(2); + expect(permutations2).toEqual([ + ['B', 'A'], + ['A', 'B'], + ]); + + const permutations6 = permutateWithoutRepetitions(['A', 'A']); + expect(permutations6.length).toBe(2); + expect(permutations6).toEqual([ + ['A', 'A'], + ['A', 'A'], + ]); + + const permutations3 = permutateWithoutRepetitions(['A', 'B', 'C']); + expect(permutations3.length).toBe(factorial(3)); + expect(permutations3).toEqual([ + ['C', 'B', 'A'], + ['B', 'C', 'A'], + ['B', 'A', 'C'], + ['C', 'A', 'B'], + ['A', 'C', 'B'], + ['A', 'B', 'C'], + ]); + + const permutations4 = permutateWithoutRepetitions(['A', 'B', 'C', 'D']); + expect(permutations4.length).toBe(factorial(4)); + expect(permutations4).toEqual([ + ['D', 'C', 'B', 'A'], + ['C', 'D', 'B', 'A'], + ['C', 'B', 'D', 'A'], + ['C', 'B', 'A', 'D'], + ['D', 'B', 'C', 'A'], + ['B', 'D', 'C', 'A'], + ['B', 'C', 'D', 'A'], + ['B', 'C', 'A', 'D'], + ['D', 'B', 'A', 'C'], + ['B', 'D', 'A', 'C'], + ['B', 'A', 'D', 'C'], + ['B', 'A', 'C', 'D'], + ['D', 'C', 'A', 'B'], + ['C', 'D', 'A', 'B'], + ['C', 'A', 'D', 'B'], + ['C', 'A', 'B', 'D'], + ['D', 'A', 'C', 'B'], + ['A', 'D', 'C', 'B'], + ['A', 'C', 'D', 'B'], + ['A', 'C', 'B', 'D'], + ['D', 'A', 'B', 'C'], + ['A', 'D', 'B', 'C'], + ['A', 'B', 'D', 'C'], + ['A', 'B', 'C', 'D'], + ]); + + const permutations5 = permutateWithoutRepetitions(['A', 'B', 'C', 'D', 'E', 'F']); + expect(permutations5.length).toBe(factorial(6)); + }); +}); diff --git a/src/algorithms/math/permutations/permutateWithRepetitions.js b/src/algorithms/math/permutations/permutateWithRepetitions.js new file mode 100644 index 00000000..25d6fcaf --- /dev/null +++ b/src/algorithms/math/permutations/permutateWithRepetitions.js @@ -0,0 +1,42 @@ +/** + * @param {*[]} permutationOptions + * @return {*[]} + */ +export default function permutateWithRepetitions(permutationOptions) { + // There is no permutations for empty array. + if (!permutationOptions || permutationOptions.length === 0) { + return []; + } + + // There is only one permutation for the 1-element array. + if (permutationOptions.length === 1) { + return [permutationOptions]; + } + + // Let's create initial set of permutations. + let previousPermutations = permutationOptions.map(option => [option]); + let currentPermutations = []; + let permutationSize = 1; + + // While the size of each permutation is less then or equal to options length... + while (permutationSize < permutationOptions.length) { + // Reset all current permutations. + currentPermutations = []; + + for (let permIndex = 0; permIndex < previousPermutations.length; permIndex += 1) { + for (let optionIndex = 0; optionIndex < permutationOptions.length; optionIndex += 1) { + let currentPermutation = previousPermutations[permIndex]; + currentPermutation = currentPermutation.concat([permutationOptions[optionIndex]]); + currentPermutations.push(currentPermutation); + } + } + + // Make current permutations to be the previous ones. + previousPermutations = currentPermutations.slice(0); + + // Increase permutation size counter. + permutationSize += 1; + } + + return currentPermutations; +} diff --git a/src/algorithms/math/permutations/permutateWithoutRepetitions.js b/src/algorithms/math/permutations/permutateWithoutRepetitions.js new file mode 100644 index 00000000..afdbd7d4 --- /dev/null +++ b/src/algorithms/math/permutations/permutateWithoutRepetitions.js @@ -0,0 +1,39 @@ +/** + * @param {*[]} permutationOptions + * @return {*[]} + */ +export default function permutateWithoutRepetitions(permutationOptions) { + if (permutationOptions.length === 0) { + return []; + } + + if (permutationOptions.length === 1) { + return [permutationOptions]; + } + + const permutations = []; + + // Get all permutations of length (n - 1). + const previousOptions = permutationOptions.slice(0, permutationOptions.length - 1); + const previousPermutations = permutateWithoutRepetitions(previousOptions); + + // Insert last option into every possible position of every previous permutation. + const lastOption = permutationOptions.slice(permutationOptions.length - 1); + + for ( + let permutationIndex = 0; + permutationIndex < previousPermutations.length; + permutationIndex += 1 + ) { + const currentPermutation = previousPermutations[permutationIndex]; + + // Insert last option into every possible position of currentPermutation. + for (let positionIndex = 0; positionIndex <= currentPermutation.length; positionIndex += 1) { + const permutationPrefix = currentPermutation.slice(0, positionIndex); + const permutationSuffix = currentPermutation.slice(positionIndex); + permutations.push(permutationPrefix.concat(lastOption, permutationSuffix)); + } + } + + return permutations; +} diff --git a/src/algorithms/string/combinations/__test__/combineWithoutRepetitions.test.js b/src/algorithms/string/combinations/__test__/combineWithoutRepetitions.test.js deleted file mode 100644 index 6d2987ec..00000000 --- a/src/algorithms/string/combinations/__test__/combineWithoutRepetitions.test.js +++ /dev/null @@ -1,40 +0,0 @@ -import combineWithoutRepetitions from '../combineWithoutRepetitions'; -import factorial from '../../../math/factorial/factorial'; - -describe('combineWithoutRepetitions', () => { - it('should combine string without repetitions', () => { - expect(combineWithoutRepetitions('AB', 3)).toEqual([]); - expect(combineWithoutRepetitions('AB', 1)).toEqual(['A', 'B']); - expect(combineWithoutRepetitions('A', 1)).toEqual(['A']); - expect(combineWithoutRepetitions('AB', 2)).toEqual(['AB']); - expect(combineWithoutRepetitions('ABC', 2)).toEqual(['AB', 'AC', 'BC']); - expect(combineWithoutRepetitions('ABC', 3)).toEqual(['ABC']); - expect(combineWithoutRepetitions('ABCD', 3)).toEqual([ - 'ABC', - 'ABD', - 'ACD', - 'BCD', - ]); - expect(combineWithoutRepetitions('ABCDE', 3)).toEqual([ - 'ABC', - 'ABD', - 'ABE', - 'ACD', - 'ACE', - 'ADE', - 'BCD', - 'BCE', - 'BDE', - 'CDE', - ]); - - const combinationOptions = 'ABCDEFGH'; - const combinationSlotsNumber = 4; - const combinations = combineWithoutRepetitions(combinationOptions, combinationSlotsNumber); - const n = combinationOptions.length; - const r = combinationSlotsNumber; - const expectedNumberOfCombinations = factorial(n) / (factorial(r) * factorial(n - r)); - - expect(combinations.length).toBe(expectedNumberOfCombinations); - }); -}); diff --git a/src/algorithms/string/permutations/__test__/permutateWithRepetitions.test.js b/src/algorithms/string/permutations/__test__/permutateWithRepetitions.test.js deleted file mode 100644 index a43ec7db..00000000 --- a/src/algorithms/string/permutations/__test__/permutateWithRepetitions.test.js +++ /dev/null @@ -1,53 +0,0 @@ -import permutateWithRepetition from '../permutateWithRepetitions'; - -describe('permutateWithRepetition', () => { - it('should permutate string with repetition', () => { - const permutations0 = permutateWithRepetition(''); - expect(permutations0).toEqual([]); - - const permutations1 = permutateWithRepetition('A'); - expect(permutations1).toEqual(['A']); - - const permutations2 = permutateWithRepetition('AB'); - expect(permutations2).toEqual([ - 'AA', - 'AB', - 'BA', - 'BB', - ]); - - const permutations3 = permutateWithRepetition('ABC'); - expect(permutations3).toEqual([ - 'AAA', - 'AAB', - 'AAC', - 'ABA', - 'ABB', - 'ABC', - 'ACA', - 'ACB', - 'ACC', - 'BAA', - 'BAB', - 'BAC', - 'BBA', - 'BBB', - 'BBC', - 'BCA', - 'BCB', - 'BCC', - 'CAA', - 'CAB', - 'CAC', - 'CBA', - 'CBB', - 'CBC', - 'CCA', - 'CCB', - 'CCC', - ]); - - const permutations4 = permutateWithRepetition('ABCD'); - expect(permutations4.length).toBe(4 * 4 * 4 * 4); - }); -}); diff --git a/src/algorithms/string/permutations/__test__/permutateWithoutRepetitions.test.js b/src/algorithms/string/permutations/__test__/permutateWithoutRepetitions.test.js deleted file mode 100644 index 0130fd0a..00000000 --- a/src/algorithms/string/permutations/__test__/permutateWithoutRepetitions.test.js +++ /dev/null @@ -1,69 +0,0 @@ -import permutateWithoutRepetitions from '../permutateWithoutRepetitions'; -import factorial from '../../../math/factorial/factorial'; - -describe('permutateString', () => { - it('should permutate string', () => { - const permutations0 = permutateWithoutRepetitions(''); - expect(permutations0).toEqual([]); - - const permutations1 = permutateWithoutRepetitions('A'); - expect(permutations1).toEqual(['A']); - - const permutations2 = permutateWithoutRepetitions('AB'); - expect(permutations2.length).toBe(2); - expect(permutations2).toEqual([ - 'BA', - 'AB', - ]); - - const permutations6 = permutateWithoutRepetitions('AA'); - expect(permutations6.length).toBe(2); - expect(permutations6).toEqual([ - 'AA', - 'AA', - ]); - - const permutations3 = permutateWithoutRepetitions('ABC'); - expect(permutations3.length).toBe(factorial(3)); - expect(permutations3).toEqual([ - 'CBA', - 'BCA', - 'BAC', - 'CAB', - 'ACB', - 'ABC', - ]); - - const permutations4 = permutateWithoutRepetitions('ABCD'); - expect(permutations4.length).toBe(factorial(4)); - expect(permutations4).toEqual([ - 'DCBA', - 'CDBA', - 'CBDA', - 'CBAD', - 'DBCA', - 'BDCA', - 'BCDA', - 'BCAD', - 'DBAC', - 'BDAC', - 'BADC', - 'BACD', - 'DCAB', - 'CDAB', - 'CADB', - 'CABD', - 'DACB', - 'ADCB', - 'ACDB', - 'ACBD', - 'DABC', - 'ADBC', - 'ABDC', - 'ABCD', - ]); - - const permutations5 = permutateWithoutRepetitions('ABCDEF'); - expect(permutations5.length).toBe(factorial(6)); - }); -}); diff --git a/src/algorithms/string/permutations/permutateWithRepetitions.js b/src/algorithms/string/permutations/permutateWithRepetitions.js deleted file mode 100644 index 1bae1df3..00000000 --- a/src/algorithms/string/permutations/permutateWithRepetitions.js +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @param {string} str - * @return {string[]} - */ -export default function permutateWithRepetition(str) { - // There is no permutations for empty string. - if (!str || str.length === 0) { - return []; - } - - // There is only one permutation for the 1-character string. - if (str.length === 1) { - return [str]; - } - - // Let's create initial set of permutations. - let previousPermutations = Array.from(str); - let currentPermutations = []; - let permutationSize = 1; - - // While the size of each permutation is less then or equal to string length... - while (permutationSize < str.length) { - // Reset all current permutations. - currentPermutations = []; - - for (let pemIndex = 0; pemIndex < previousPermutations.length; pemIndex += 1) { - for (let charIndex = 0; charIndex < str.length; charIndex += 1) { - const currentPermutation = previousPermutations[pemIndex] + str[charIndex]; - currentPermutations.push(currentPermutation); - } - } - - // Make current permutations to be the previous ones. - previousPermutations = currentPermutations.slice(0); - - // Increase permutation size counter. - permutationSize += 1; - } - - return currentPermutations; -} diff --git a/src/algorithms/string/permutations/permutateWithoutRepetitions.js b/src/algorithms/string/permutations/permutateWithoutRepetitions.js deleted file mode 100644 index 0a034636..00000000 --- a/src/algorithms/string/permutations/permutateWithoutRepetitions.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * @param {string} str - * @return {string[]} - */ -export default function permutateWithoutRepetitions(str) { - if (str.length === 0) { - return []; - } - - if (str.length === 1) { - return [str]; - } - - const permutations = []; - - // Get all permutations of string of length (n - 1). - const previousString = str.substring(0, str.length - 1); - const previousPermutations = permutateWithoutRepetitions(previousString); - - // Insert last character into every possible position of every previous permutation. - const lastCharacter = str.substring(str.length - 1); - - for ( - let permutationIndex = 0; - permutationIndex < previousPermutations.length; - permutationIndex += 1 - ) { - const currentPermutation = previousPermutations[permutationIndex]; - - // Insert strLastCharacter into every possible position of currentPermutation. - for (let positionIndex = 0; positionIndex <= currentPermutation.length; positionIndex += 1) { - const permutationPrefix = currentPermutation.substr(0, positionIndex); - const permutationSuffix = currentPermutation.substr(positionIndex); - permutations.push(permutationPrefix + lastCharacter + permutationSuffix); - } - } - - return permutations; -}