diff --git a/16_permutations/README.md b/16_permutations/README.md new file mode 100644 index 00000000000..de5569ccbc2 --- /dev/null +++ b/16_permutations/README.md @@ -0,0 +1,11 @@ +# Exercise 16 - permutations + +Write a function that takes in an empty array or an input array of an consecutive positive integers, starting at 1, and returns an array of all possible permutations of the original array + +The integers will not repeat. + +```javascript +permutations([1, 2, 3]); // [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] +// An empty set has a single permutation, 0! = 1 +permutations([]); // [[]] +``` diff --git a/16_permutations/permutations.js b/16_permutations/permutations.js new file mode 100644 index 00000000000..c7380ec3640 --- /dev/null +++ b/16_permutations/permutations.js @@ -0,0 +1,6 @@ +const permutations = function() { + +}; + +// Do not edit below this line +module.exports = permutations; diff --git a/16_permutations/permutations.spec.js b/16_permutations/permutations.spec.js new file mode 100644 index 00000000000..69ee0a1ae9b --- /dev/null +++ b/16_permutations/permutations.spec.js @@ -0,0 +1,64 @@ +const permutations = require("./permutations"); + +describe("permutations", () => { + test("1 possible permutation for a set containing 0 numbers", () => { + expect(permutations([])).toEqual([[]]); + }); + + test.skip("1 possible permutation for a set containing 1 number", () => { + expect(permutations([1])).toEqual([[1]]); + }); + + test.skip("2 possible permutations for a set containing 2 numbers", () => { + expect(permutations([1, 2]).sort()).toEqual( + [ + [1, 2], + [2, 1], + ].sort(), + ); + }); + + test.skip("6 possible permutations for a set containing 3 numbers", () => { + expect(permutations([1, 2, 3]).sort()).toEqual( + [ + [1, 2, 3], + [1, 3, 2], + [2, 1, 3], + [2, 3, 1], + [3, 1, 2], + [3, 2, 1], + ].sort(), + ); + }); + + test.skip("24 possible permutations for a set containing 4 numbers", () => { + expect(permutations([1, 2, 3, 4]).sort()).toEqual( + [ + [1, 2, 3, 4], + [1, 2, 4, 3], + [1, 3, 2, 4], + [1, 3, 4, 2], + [1, 4, 2, 3], + [1, 4, 3, 2], + [2, 1, 3, 4], + [2, 1, 4, 3], + [2, 3, 1, 4], + [2, 3, 4, 1], + [2, 4, 1, 3], + [2, 4, 3, 1], + [3, 1, 2, 4], + [3, 1, 4, 2], + [3, 2, 1, 4], + [3, 2, 4, 1], + [3, 4, 1, 2], + [3, 4, 2, 1], + [4, 1, 2, 3], + [4, 1, 3, 2], + [4, 2, 1, 3], + [4, 2, 3, 1], + [4, 3, 1, 2], + [4, 3, 2, 1], + ].sort(), + ); + }); +}); diff --git a/16_permutations/solution/permutations-solution.js b/16_permutations/solution/permutations-solution.js new file mode 100644 index 00000000000..fb3f2d5cf79 --- /dev/null +++ b/16_permutations/solution/permutations-solution.js @@ -0,0 +1,25 @@ +const permutations = function (array, index = 0, results = []) { + if (index == array.length) { + // We have formed a valid permutation. + + // the [...array] syntax is a way to clone the contents of the array. + // because we do not want to pass a reference to the array, as that would mean + // that each item in `results` will be the same item + results.push([...array]); + return results; + } + + for (let i = index; i < array.length; i++) { + // We use "destructuring assignment" here to swap the values of array[index] and array[i] + // + // More info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment + [array[index], array[i]] = [array[i], array[index]]; + permutations(array, index + 1, results); + [array[index], array[i]] = [array[i], array[index]]; + } + + return results; +}; + +// Do not edit below this line +module.exports = permutations; diff --git a/16_permutations/solution/permutations-solution.spec.js b/16_permutations/solution/permutations-solution.spec.js new file mode 100644 index 00000000000..2f3a393f495 --- /dev/null +++ b/16_permutations/solution/permutations-solution.spec.js @@ -0,0 +1,60 @@ +const permutations = require("./permutations-solution"); + +describe("permutations", () => { + test("1 possible permutation for a set containing 0 numbers", () => { + expect(permutations([])).toEqual([[]]); + }); + test("1 possible permutation for a set containing 1 number", () => { + expect(permutations([1])).toEqual([[1]]); + }); + test("2 possible permutations for a set containing 2 numbers", () => { + expect(permutations([1, 2]).sort()).toEqual( + [ + [1, 2], + [2, 1], + ].sort(), + ); + }); + test("6 possible permutations for a set containing 3 numbers", () => { + expect(permutations([1, 2, 3]).sort()).toEqual( + [ + [1, 2, 3], + [1, 3, 2], + [2, 1, 3], + [2, 3, 1], + [3, 1, 2], + [3, 2, 1], + ].sort(), + ); + }); + test("24 possible permutations for a set containing 4 numbers", () => { + expect(permutations([1, 2, 3, 4]).sort()).toEqual( + [ + [1, 2, 3, 4], + [1, 2, 4, 3], + [1, 3, 2, 4], + [1, 3, 4, 2], + [1, 4, 2, 3], + [1, 4, 3, 2], + [2, 1, 3, 4], + [2, 1, 4, 3], + [2, 3, 1, 4], + [2, 3, 4, 1], + [2, 4, 1, 3], + [2, 4, 3, 1], + [3, 1, 2, 4], + [3, 1, 4, 2], + [3, 2, 1, 4], + [3, 2, 4, 1], + [3, 4, 1, 2], + [3, 4, 2, 1], + [4, 1, 2, 3], + [4, 1, 3, 2], + [4, 2, 1, 3], + [4, 2, 3, 1], + [4, 3, 1, 2], + [4, 3, 2, 1], + ].sort(), + ); + }); +});