From 4434e964136853010519cfba0bc6ba454915b5d2 Mon Sep 17 00:00:00 2001 From: Oleksii Trekhleb Date: Tue, 17 Apr 2018 20:28:35 +0300 Subject: [PATCH] Add permutations and combinations. --- src/algorithms/string/combinations/README.md | 18 +++++++ .../__test__/permutateWithRepetitions.test.js | 53 +++++++++++++++++++ .../permutations/permutateWithRepetitions.js | 41 ++++++++++++++ .../permutateWithoutRepetitions.js | 4 ++ 4 files changed, 116 insertions(+) create mode 100644 src/algorithms/string/combinations/README.md create mode 100644 src/algorithms/string/permutations/__test__/permutateWithRepetitions.test.js create mode 100644 src/algorithms/string/permutations/permutateWithRepetitions.js diff --git a/src/algorithms/string/combinations/README.md b/src/algorithms/string/combinations/README.md new file mode 100644 index 000000000..a4d58408f --- /dev/null +++ b/src/algorithms/string/combinations/README.md @@ -0,0 +1,18 @@ +# Combinations + +When the order doesn't matter, it is a **Combination**. + +When the order **does** matter it is a **Permutation**. + +**"My fruit salad is a combination of apples, grapes and bananas"** +We don't care what order the fruits are in, they could also be +"bananas, grapes and apples" or "grapes, apples and bananas", +its the same fruit salad. + +## Combinations without repetitions + +## Combinations with repetitions + +## References + +[Math Is Fun](https://www.mathsisfun.com/combinatorics/combinations-permutations.html) diff --git a/src/algorithms/string/permutations/__test__/permutateWithRepetitions.test.js b/src/algorithms/string/permutations/__test__/permutateWithRepetitions.test.js new file mode 100644 index 000000000..a43ec7dbe --- /dev/null +++ b/src/algorithms/string/permutations/__test__/permutateWithRepetitions.test.js @@ -0,0 +1,53 @@ +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/permutateWithRepetitions.js b/src/algorithms/string/permutations/permutateWithRepetitions.js new file mode 100644 index 000000000..1bae1df3b --- /dev/null +++ b/src/algorithms/string/permutations/permutateWithRepetitions.js @@ -0,0 +1,41 @@ +/** + * @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 index c1a376a47..0a0346361 100644 --- a/src/algorithms/string/permutations/permutateWithoutRepetitions.js +++ b/src/algorithms/string/permutations/permutateWithoutRepetitions.js @@ -1,3 +1,7 @@ +/** + * @param {string} str + * @return {string[]} + */ export default function permutateWithoutRepetitions(str) { if (str.length === 0) { return [];