Skip to content

Instantly share code, notes, and snippets.

@j-
Created November 29, 2018 06:43
Show Gist options
  • Save j-/c543298f6cccda91ac625cbbabdabc46 to your computer and use it in GitHub Desktop.
Save j-/c543298f6cccda91ac625cbbabdabc46 to your computer and use it in GitHub Desktop.
interface Permutation extends Array<number> {}
interface PermutationList extends Array<Permutation> {}
/**
* Gets all permutations of a given list of digits. Results are not guaranteed
* to be uniqe.
*/
export const getPermutations = (input: Permutation): PermutationList => (
input.length <= 1 ? [input] : input.reduce((result, n, i, arr) => ([
...result,
...getPermutations([
...arr.slice(0, i),
...arr.slice(i + 1),
]).map((permutation) => (
[n, ...permutation]
)),
]), [])
);
/**
* Determines if two input lists contain the same items in the same order.
*/
export const arraysEqual = <T>(left: T[], right: T[]) => (
left.length === right.length &&
left.every((item, i) => item === right[i])
);
/**
* Compares two permutations and orders them such that the one with lower
* numbers early on come first.
*
* @example
*
* permutationComparator(
* [0, 1, 3, 2],
* [0, 1, 2, 3]
* ) === -1
*
* permutationComparator(
* [0, 1, 3, 2],
* [1, 0, 2, 3]
* ) === 1
*/
export const permutationComparator = (left: Permutation, right: Permutation) => (
left.reduce((result, item, i) => result || (
item < right[i] ? -1 :
item > right[i] ? 1 :
0
), 0)
);
/**
* Given an input list of digits, returns a list of all unique permutations of
* those digits.
*/
export const getUniquePermutations = (input: Permutation): PermutationList => (
getPermutations(input)
.sort(permutationComparator)
.filter((permutation, i, arr) => (
i === 0 ||
!arraysEqual(permutation, arr[i - 1])
))
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment