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...