Skip to content

Instantly share code, notes, and snippets.

@conartist6
Last active August 29, 2019 17:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save conartist6/da1ec9ba4bf2d506ce7a4818f3fc503d to your computer and use it in GitHub Desktop.
Save conartist6/da1ec9ba4bf2d506ce7a4818f3fc503d to your computer and use it in GitHub Desktop.
Permutations generator
function swap(arr, aIdx, bIdx) {
if (aIdx < 0 || aIdx >= arr.length) throw new TypeError();
if (bIdx < 0 || bIdx >= arr.length) throw new TypeError();
const temp = arr[aIdx];
arr[aIdx] = arr[bIdx];
arr[bIdx] = temp;
}
function shiftToEnd(arr, idx) {
if (idx < 0 || idx >= arr.length) throw new TypeError();
const toShift = arr[idx]; // 1, 2, 3
const end = arr.length - 1;
for (let i = idx; i < end; i++) {
arr[i] = arr[i + 1];
}
arr[arr.length - 1] = toShift;
}
export function permutationsRec(arr, k = arr.length, start = 0, perms = []) {
if (start === k) {
perms.push(arr.slice(0, k));
} else {
for (let i = start; i < arr.length; i++) {
swap(arr, start, i);
permutationsRec(arr, k, start + 1, perms);
}
shiftToEnd(arr, start);
}
return perms;
}
export function* permutations(arr, k = arr.length) {
const ist = [0]; // i stack
let start = 0; // start === ist.length - 1
while (ist.length > 1 || ist[0] < arr.length) {
swap(arr, start, start + ist[start]);
if (ist.length === k) {
yield arr.slice(0, k);
++ist[start];
} else {
ist.push(0);
start++;
}
while (ist[start] === arr.length - start) {
shiftToEnd(arr, start);
ist.pop();
start--;
ist[start]++;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment