mirror of
https://github.moeyy.xyz/https://github.com/trekhleb/javascript-algorithms.git
synced 2024-12-26 23:21:18 +08:00
Simplify permutateWithoutRepetitions algorithm.
This commit is contained in:
parent
db7ab9e299
commit
00f75028bf
@ -3,9 +3,6 @@ import factorial from '../../../math/factorial/factorial';
|
|||||||
|
|
||||||
describe('permutateWithoutRepetitions', () => {
|
describe('permutateWithoutRepetitions', () => {
|
||||||
it('should permutate string', () => {
|
it('should permutate string', () => {
|
||||||
const permutations0 = permutateWithoutRepetitions([]);
|
|
||||||
expect(permutations0).toEqual([]);
|
|
||||||
|
|
||||||
const permutations1 = permutateWithoutRepetitions(['A']);
|
const permutations1 = permutateWithoutRepetitions(['A']);
|
||||||
expect(permutations1).toEqual([
|
expect(permutations1).toEqual([
|
||||||
['A'],
|
['A'],
|
||||||
@ -14,8 +11,8 @@ describe('permutateWithoutRepetitions', () => {
|
|||||||
const permutations2 = permutateWithoutRepetitions(['A', 'B']);
|
const permutations2 = permutateWithoutRepetitions(['A', 'B']);
|
||||||
expect(permutations2.length).toBe(2);
|
expect(permutations2.length).toBe(2);
|
||||||
expect(permutations2).toEqual([
|
expect(permutations2).toEqual([
|
||||||
['B', 'A'],
|
|
||||||
['A', 'B'],
|
['A', 'B'],
|
||||||
|
['B', 'A'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const permutations6 = permutateWithoutRepetitions(['A', 'A']);
|
const permutations6 = permutateWithoutRepetitions(['A', 'A']);
|
||||||
@ -28,41 +25,41 @@ describe('permutateWithoutRepetitions', () => {
|
|||||||
const permutations3 = permutateWithoutRepetitions(['A', 'B', 'C']);
|
const permutations3 = permutateWithoutRepetitions(['A', 'B', 'C']);
|
||||||
expect(permutations3.length).toBe(factorial(3));
|
expect(permutations3.length).toBe(factorial(3));
|
||||||
expect(permutations3).toEqual([
|
expect(permutations3).toEqual([
|
||||||
['C', 'B', 'A'],
|
|
||||||
['B', 'C', 'A'],
|
|
||||||
['B', 'A', 'C'],
|
|
||||||
['C', 'A', 'B'],
|
|
||||||
['A', 'C', 'B'],
|
|
||||||
['A', 'B', 'C'],
|
['A', 'B', 'C'],
|
||||||
|
['B', 'A', 'C'],
|
||||||
|
['B', 'C', 'A'],
|
||||||
|
['A', 'C', 'B'],
|
||||||
|
['C', 'A', 'B'],
|
||||||
|
['C', 'B', 'A'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const permutations4 = permutateWithoutRepetitions(['A', 'B', 'C', 'D']);
|
const permutations4 = permutateWithoutRepetitions(['A', 'B', 'C', 'D']);
|
||||||
expect(permutations4.length).toBe(factorial(4));
|
expect(permutations4.length).toBe(factorial(4));
|
||||||
expect(permutations4).toEqual([
|
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'],
|
['A', 'B', 'C', 'D'],
|
||||||
|
['B', 'A', 'C', 'D'],
|
||||||
|
['B', 'C', 'A', 'D'],
|
||||||
|
['B', 'C', 'D', 'A'],
|
||||||
|
['A', 'C', 'B', 'D'],
|
||||||
|
['C', 'A', 'B', 'D'],
|
||||||
|
['C', 'B', 'A', 'D'],
|
||||||
|
['C', 'B', 'D', 'A'],
|
||||||
|
['A', 'C', 'D', 'B'],
|
||||||
|
['C', 'A', 'D', 'B'],
|
||||||
|
['C', 'D', 'A', 'B'],
|
||||||
|
['C', 'D', 'B', 'A'],
|
||||||
|
['A', 'B', 'D', 'C'],
|
||||||
|
['B', 'A', 'D', 'C'],
|
||||||
|
['B', 'D', 'A', 'C'],
|
||||||
|
['B', 'D', 'C', 'A'],
|
||||||
|
['A', 'D', 'B', 'C'],
|
||||||
|
['D', 'A', 'B', 'C'],
|
||||||
|
['D', 'B', 'A', 'C'],
|
||||||
|
['D', 'B', 'C', 'A'],
|
||||||
|
['A', 'D', 'C', 'B'],
|
||||||
|
['D', 'A', 'C', 'B'],
|
||||||
|
['D', 'C', 'A', 'B'],
|
||||||
|
['D', 'C', 'B', 'A'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const permutations5 = permutateWithoutRepetitions(['A', 'B', 'C', 'D', 'E', 'F']);
|
const permutations5 = permutateWithoutRepetitions(['A', 'B', 'C', 'D', 'E', 'F']);
|
||||||
|
@ -3,35 +3,27 @@
|
|||||||
* @return {*[]}
|
* @return {*[]}
|
||||||
*/
|
*/
|
||||||
export default function permutateWithoutRepetitions(permutationOptions) {
|
export default function permutateWithoutRepetitions(permutationOptions) {
|
||||||
if (permutationOptions.length === 0) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (permutationOptions.length === 1) {
|
if (permutationOptions.length === 1) {
|
||||||
return [permutationOptions];
|
return [permutationOptions];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Init permutations array.
|
||||||
const permutations = [];
|
const permutations = [];
|
||||||
|
|
||||||
// Get all permutations of length (n - 1).
|
// Get all permutations for permutationOptions excluding the first element.
|
||||||
const previousOptions = permutationOptions.slice(0, permutationOptions.length - 1);
|
const smallerPermutations = permutateWithoutRepetitions(permutationOptions.slice(1));
|
||||||
const previousPermutations = permutateWithoutRepetitions(previousOptions);
|
|
||||||
|
|
||||||
// Insert last option into every possible position of every previous permutation.
|
// Insert first option into every possible position of every smaller permutation.
|
||||||
const lastOption = permutationOptions.slice(permutationOptions.length - 1);
|
const firstOption = permutationOptions[0];
|
||||||
|
|
||||||
for (
|
for (let permIndex = 0; permIndex < smallerPermutations.length; permIndex += 1) {
|
||||||
let permutationIndex = 0;
|
const smallerPermutation = smallerPermutations[permIndex];
|
||||||
permutationIndex < previousPermutations.length;
|
|
||||||
permutationIndex += 1
|
|
||||||
) {
|
|
||||||
const currentPermutation = previousPermutations[permutationIndex];
|
|
||||||
|
|
||||||
// Insert last option into every possible position of currentPermutation.
|
// Insert first option into every possible position of smallerPermutation.
|
||||||
for (let positionIndex = 0; positionIndex <= currentPermutation.length; positionIndex += 1) {
|
for (let positionIndex = 0; positionIndex <= smallerPermutation.length; positionIndex += 1) {
|
||||||
const permutationPrefix = currentPermutation.slice(0, positionIndex);
|
const permutationPrefix = smallerPermutation.slice(0, positionIndex);
|
||||||
const permutationSuffix = currentPermutation.slice(positionIndex);
|
const permutationSuffix = smallerPermutation.slice(positionIndex);
|
||||||
permutations.push(permutationPrefix.concat(lastOption, permutationSuffix));
|
permutations.push(permutationPrefix.concat([firstOption], permutationSuffix));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user