historical-permutations
Version:
A library of historical permutation algorithms from 1950s-present implemented in JavaScript.
85 lines (75 loc) • 2.72 kB
JavaScript
const { reverseNonMutate } = require("../utils/utils");
function weight1graph(startingPermutation, loopNo) {
const permutationCycle = startingPermutation.reduce(
(outputArray, element, index) =>
index !== startingPermutation.length - 1
? [...outputArray, element]
: outputArray,
startingPermutation
);
const arrayCut = permutationCycle.length - startingPermutation.length;
const outputGraph =
loopNo !== 0
? permutationCycle.slice(startingPermutation.length)
: permutationCycle.map(x => x);
return [outputGraph, permutationCycle.slice(arrayCut)];
}
function selectSwapPositions(currentLoopNo, arrayOfSwaps) {
const levelFound = arrayOfSwaps.findIndex(innerArray => {
return innerArray[1].includes(currentLoopNo);
});
return arrayOfSwaps[levelFound][0];
}
function graphConnector(startingPermutation, loopNo, hierarchy) {
const amountToReverse = selectSwapPositions(loopNo, hierarchy);
const newElements = reverseNonMutate(
startingPermutation.slice(0, amountToReverse)
);
const lastElements = startingPermutation.slice(amountToReverse);
return [[...lastElements, ...newElements], newElements];
}
function recursiveCounter(arrayIn, n) {
return arrayIn.reduce((output, value, index) => {
if (index % (n - 1) === n - 2) return [...output, value];
return output;
}, []);
}
function swapPositions(n) {
const factArray = Array.from({ length: n - 1 }, (value, index) => index + 1);
const factorial = factArray.reduce((output, value) => {
return output * value;
}, 1);
const factCountArray = Array.from(
{ length: factorial },
(value, index) => index
);
const arrayOfPositions = [[2, factCountArray]];
for (let i = n; i > 2; i--) {
arrayOfPositions.push([
n - i + 3,
recursiveCounter(arrayOfPositions[arrayOfPositions.length - 1][1], i)
]);
}
return arrayOfPositions.reverse();
}
function superpermutation(n) {
const hierarchy = swapPositions(n);
const startingArray = Array.from({ length: n }, (value, index) => index + 1);
const outputArray = [];
let currentArray = startingArray.map(x => x);
const factorial = startingArray.reduce((total, number) => number * total, 1);
const totalLoops = factorial / n;
for (let i = 0; i < totalLoops; i++) {
const newPerms = weight1graph(currentArray, i);
newPerms[0].forEach(newValue => {
outputArray.push(newValue);
});
const navigationPerms = graphConnector(newPerms[1], i, hierarchy);
navigationPerms[1].forEach(newValue => {
if (i < totalLoops - 1) outputArray.push(newValue);
});
currentArray = navigationPerms[0];
}
return outputArray;
}
module.exports = superpermutation;