JSFiddle - React, Tailwind, and code Playground
by jonahe
JavaScript
// Supermutate.js
// ==============
//
// by Greg Egan
//
// Generates superpermutations using a method adapted
// from "Hamiltonicity of the Cayley Digraph ..." by Aaron Williams.
//
// This method is described on my web page:
//
// http://www.gregegan.net/SCIENCE/Superpermutations/Superpermutations.html
// Constructor for an object that generates superpermutations
function Supermutate(n)
{
this.n=n;
this.fn=Supermutate.factorial(n);
this.available=this.fn;
this.q=new Array(n);
this.r=new Array(n);
this.remap=new Array(n);
this.c=new Array(n);
for (var i=0;i<n;i++)
{
this.r[i]=n-i; // Permutation n n-1 n-2 ... 3 2 1
this.q[i]=1+(n-i)%n; // Permutation 1 n n-1 ....... 3 2
};
this.p=Supermutate.successor2(this.q); // Permutation n-1 n-2 ... 3 2 n 1
for (var i=0;i<n;i++)
{
this.remap[this.p[i]-1]=i+1; // Maps digits of p to 1 2 3 ... n
this.c[i]=this.p[i]; // Set current permutation to p
};
this.supply=n;
}
// Get current permutation (either full permutation, or just new digits to append to superpermutation), optionally mapped to start at identity.
// Then advance to next in sequence.
Supermutate.prototype.get = function (full,mapped,cycle)
{
if (this.available==0)
{
// We have supplied the whole list. Optionally reset and start again.
if (cycle)
{
for (var i=0;i<this.n;i++) this.c[i]=this.p[i];
this.available=this.fn;
this.supply=this.n;
}
else return [];
};
var res = mapped ? this.map(this.c) : this.c.slice();
if (!full) res = res.slice(-this.supply);
this.available--;
if (this.available!=0)
{
if (Supermutate.weight2edge(this.c) && !Supermutate.arrayEq(this.c,this.q))
{
this.c=Supermutate.successor2(this.c);
this.supply=2;
}
else
{
this.c=Supermutate.successor1(this.c);
this.supply=1;
};
};
return res;
}
// Factorial
Supermutate.factorial = function(n)
{
if (n<=1) return 1;
return n*Supermutate.factorial(n-1);
};
// Compare array...