Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,2 @@
---
from: http://rosettacode.org/wiki/Superpermutation_minimisation

View file

@ -0,0 +1,27 @@
A superpermutation of N different characters is a string consisting of an arrangement of multiple copies of those N different characters in which every permutation of those characters can be found as a substring.
For example, representing the characters as A..Z, using N=2 we choose to use the first two characters 'AB'. <br>
The permutations of 'AB' are the two, (i.e. two-factorial), strings: 'AB' and 'BA'.
A too obvious method of generating a superpermutation is to just join all the permutations together forming 'ABBA'.
A little thought will produce the shorter (in fact the shortest) superpermutation of 'ABA' - it contains 'AB' at the beginning and contains 'BA' from the middle to the end.
The "too obvious" method of creation generates a string of length N!*N. Using this as a yardstick, the task is to investigate other methods of generating superpermutations of N from 1-to-7 characters, that never generate larger superpermutations.
Show descriptions and comparisons of algorithms used here, and select the "Best" algorithm as being the one generating shorter superpermutations.
The problem of generating the shortest superpermutation for each N ''might'' be NP complete, although the minimal strings for small values of N have been found by brute -force searches.
{{Template:Strings}}
;Reference:
* [http://www.njohnston.ca/2013/04/the-minimal-superpermutation-problem/ The Minimal Superpermutation Problem]. by Nathaniel Johnston.
* [http://oeis.org/A180632 oeis A180632] gives 0-5 as 0, 1, 3, 9, 33, 153. 6 is thought to be 872.
* [https://www.youtube.com/watch?v=wJGE4aEWc28 Superpermutations - Numberphile]. A video
* [https://www.youtube.com/watch?v=OZzIvl1tbPo Superpermutations: the maths problem solved by 4chan - Standupmaths]. A video of recent (2018) mathematical progress.
* [https://www.youtube.com/watch?v=_tpNuulTeSQ New Superpermutations Discovered!] Standupmaths & Numberphile.
<br><br>

View file

@ -0,0 +1,40 @@
-V MAX = 12
[Char] sp
V count = [0] * MAX
V pos = 0
F factSum(n)
V s = 0
V x = 0
V f = 1
L x < n
f *= ++x
s += f
R s
F r(n)
I n == 0
R 0B
V c = :sp[:pos - n]
I --:count[n] == 0
:count[n] = n
I !r(n - 1)
R 0B
:sp[:pos++] = c
R 1B
F superPerm(n)
:pos = n
V len = factSum(n)
I len > 0
:sp = [Char("\0")] * len
L(i) 0 .. n
:count[i] = i
L(i) 1 .. n
:sp[i - 1] = Char(code' 0.code + i)
L r(n) {}
L(n) 0 .< MAX
superPerm(n)
print(superPerm(#2) len = #..format(n, sp.len))

View file

@ -0,0 +1,48 @@
# syntax: GAWK -f SUPERPERMUTATION_MINIMISATION.AWK
# converted from C
BEGIN {
arr[0] # prevents fatal: attempt to use scalar 'arr' as an array
limit = 11
for (n=0; n<=limit; n++) {
leng = super_perm(n)
printf("%2d %d ",n,leng)
# for (i=0; i<length(arr); i++) { printf(arr[i]) } # un-comment to see the string
printf("\n")
}
exit(0)
}
function fact_sum(n, f,s,x) {
f = 1
s = x = 0
for (;x<n;) {
f *= ++x
s += f
}
return(s)
}
function super_perm(n, i,leng) {
delete arr
pos = n
leng = fact_sum(n)
for (i=0; i<leng; i++) {
arr[i] = ""
}
for (i=0; i<=n; i++) {
cnt[i] = i
}
for (i=1; i<=n; i++) {
arr[i-1] = i + "0"
}
while (r(n)) { }
return(leng)
}
function r(n, c) {
if (!n) { return(0) }
c = arr[pos-n]
if (!--cnt[n]) {
cnt[n] = n
if (!r(n-1)) { return(0) }
}
arr[pos++] = c
return(1)
}

View file

@ -0,0 +1,59 @@
#include <array>
#include <iostream>
#include <vector>
constexpr int MAX = 12;
static std::vector<char> sp;
static std::array<int, MAX> count;
static int pos = 0;
int factSum(int n) {
int s = 0;
int x = 0;
int f = 1;
while (x < n) {
f *= ++x;
s += f;
}
return s;
}
bool r(int n) {
if (n == 0) {
return false;
}
char c = sp[pos - n];
if (--count[n] == 0) {
count[n] = n;
if (!r(n - 1)) {
return false;
}
}
sp[pos++] = c;
return true;
}
void superPerm(int n) {
pos = n;
int len = factSum(n);
if (len > 0) {
sp.resize(len);
}
for (size_t i = 0; i <= n; i++) {
count[i] = i;
}
for (size_t i = 1; i <= n; i++) {
sp[i - 1] = '0' + i;
}
while (r(n)) {}
}
int main() {
for (size_t n = 0; n < MAX; n++) {
superPerm(n);
std::cout << "superPerm(" << n << ") len = " << sp.size() << '\n';
}
return 0;
}

View file

@ -0,0 +1,58 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 12
char *super = 0;
int pos, cnt[MAX];
// 1! + 2! + ... + n!
int fact_sum(int n)
{
int s, x, f;
for (s = 0, x = 0, f = 1; x < n; f *= ++x, s += f);
return s;
}
int r(int n)
{
if (!n) return 0;
char c = super[pos - n];
if (!--cnt[n]) {
cnt[n] = n;
if (!r(n-1)) return 0;
}
super[pos++] = c;
return 1;
}
void superperm(int n)
{
int i, len;
pos = n;
len = fact_sum(n);
super = realloc(super, len + 1);
super[len] = '\0';
for (i = 0; i <= n; i++) cnt[i] = i;
for (i = 1; i <= n; i++) super[i - 1] = i + '0';
while (r(n));
}
int main(void)
{
int n;
for (n = 0; n < MAX; n++) {
printf("superperm(%2d) ", n);
superperm(n);
printf("len = %d", (int)strlen(super));
// uncomment next line to see the string itself
// printf(": %s", super);
putchar('\n');
}
return 0;
}

View file

@ -0,0 +1,45 @@
import std.stdio, std.ascii, std.algorithm, core.memory, permutations2;
/** Uses greedy algorithm of adding another char (or two, or three, ...)
until an unseen perm is formed in the last n chars. */
string superpermutation(in uint n) nothrow
in {
assert(n > 0 && n < uppercase.length);
} out(result) {
// It's a superpermutation.
assert(uppercase[0 .. n].dup.permutations.all!(p => result.canFind(p)));
} body {
string result = uppercase[0 .. n];
bool[const char[]] toFind;
GC.disable;
foreach (const perm; result.dup.permutations)
toFind[perm] = true;
GC.enable;
toFind.remove(result);
auto trialPerm = new char[n];
auto auxAdd = new char[n];
while (toFind.length) {
MIDDLE: foreach (immutable skip; 1 .. n) {
auxAdd[0 .. skip] = result[$ - n .. $ - n + skip];
foreach (const trialAdd; auxAdd[0 .. skip].permutations!false) {
trialPerm[0 .. n - skip] = result[$ + skip - n .. $];
trialPerm[n - skip .. $] = trialAdd[];
if (trialPerm in toFind) {
result ~= trialAdd;
toFind.remove(trialPerm);
break MIDDLE;
}
}
}
}
return result;
}
void main() {
foreach (immutable n; 1 .. 8)
n.superpermutation.length.writeln;
}

View file

@ -0,0 +1,50 @@
import std.stdio, std.range, std.algorithm, std.ascii;
enum uint nMax = 12;
__gshared char[] superperm;
__gshared uint pos;
__gshared uint[nMax] count;
/// factSum(n) = 1! + 2! + ... + n!
uint factSum(in uint n) pure nothrow @nogc @safe {
return iota(1, n + 1).map!(m => reduce!q{ a * b }(1u, iota(1, m + 1))).sum;
}
bool r(in uint n) nothrow @nogc {
if (!n)
return false;
immutable c = superperm[pos - n];
if (!--count[n]) {
count[n] = n;
if (!r(n - 1))
return false;
}
superperm[pos++] = c;
return true;
}
void superPerm(in uint n) nothrow {
static immutable chars = digits ~ uppercase;
static assert(chars.length >= nMax);
pos = n;
superperm.length = factSum(n);
foreach (immutable i; 0 .. n + 1)
count[i] = i;
foreach (immutable i; 1 .. n + 1)
superperm[i - 1] = chars[i];
while (r(n)) {}
}
void main() {
foreach (immutable n; 0 .. nMax) {
superPerm(n);
writef("superPerm(%2d) len = %d", n, superperm.length);
// Use -version=doPrint to see the string itself.
version (doPrint) write(": ", superperm);
writeln;
}
}

View file

@ -0,0 +1,78 @@
program Superpermutation_minimisation;
{$APPTYPE CONSOLE}
uses
System.SysUtils;
const
Max = 12;
var
super: ansistring;
pos: Integer;
cnt: TArray<Integer>;
function factSum(n: Integer): Uint64;
begin
var s: Uint64 := 0;
var f := 1;
var x := 0;
while x < n do
begin
inc(x);
f := f * x;
inc(s, f);
end;
Result := s;
end;
function r(n: Integer): Boolean;
begin
if n = 0 then
exit(false);
var c := super[pos - n];
dec(cnt[n]);
if cnt[n] = 0 then
begin
cnt[n] := n;
if not r(n - 1) then
exit(false);
end;
super[pos] := c;
inc(pos);
result := true;
end;
procedure SuperPerm(n: Integer);
begin
var pos := n;
var le: Uint64 := factSum(n);
SetLength(super, le);
for var i := 0 to n do
cnt[i] := i;
for var i := 1 to n do
super[i] := ansichar(i + ord('0'));
while r(n) do
;
end;
begin
SetLength(cnt, max);
for var n := 0 to max - 1 do
begin
write('superperm(', n: 2, ') ');
SuperPerm(n);
writeln('len = ', length(super));
end;
{$IFNDEF UNIX} readln; {$ENDIF}
end.

View file

@ -0,0 +1,23 @@
defmodule Superpermutation do
def minimisation(1), do: [1]
def minimisation(n) do
Enum.chunk(minimisation(n-1), n-1, 1)
|> Enum.reduce({[],nil}, fn sub,{acc,last} ->
if Enum.uniq(sub) == sub do
i = if acc==[], do: 0, else: Enum.find_index(sub, &(&1==last)) + 1
{acc ++ (Enum.drop(sub,i) ++ [n] ++ sub), List.last(sub)}
else
{acc, last}
end
end)
|> elem(0)
end
end
to_s = fn list -> Enum.map_join(list, &Integer.to_string(&1,16)) end
Enum.each(1..8, fn n ->
result = Superpermutation.minimisation(n)
:io.format "~3w: len =~8w : ", [n, length(result)]
IO.puts if n<5, do: Enum.join(result),
else: to_s.(Enum.take(result,20)) <> "...." <> to_s.(Enum.slice(result,-20..-1))
end)

View file

@ -0,0 +1,79 @@
' version 28-06-2018
' compile with: fbc -s console
Function superpermsize(n As UInteger) As UInteger
Dim As UInteger x, y, sum, fac
For x = 1 To n
fac = 1
For y = 1 To x
fac *= y
Next
sum += fac
Next
Function = sum
End Function
Function superperm(n As UInteger) As String
If n = 1 Then Return "1"
Dim As String sup_perm = "1", insert
Dim As String p, q()
Dim As UInteger a, b, i, l, x
For x = 2 To n
insert = IIf(x < 10, Str(x), Chr(x + 55))
l = Len(sup_perm)
If l > 1 Then l = Len(sup_perm) - x +2
ReDim q(l)
For i = 1 To l
p = Mid(sup_perm, i, x -1)
If x > 2 Then
For a = 0 To Len(p) -2
For b = a+1 To Len(p) -1
If p[a] = p[b] Then Continue For, For, For
Next
Next
End If
q(i) = p + insert + p
Next
sup_perm = q(1)
For i = 2 To UBound(q)
a = x -1
Do
If Right(sup_perm, a) = Left(q(i), a) Then
sup_perm += Mid(q(i), a +1)
Exit Do
End If
a -= 1
Loop
Next
Next
Function = sup_perm
End Function
' ------=< MAIN >=------
Dim As String superpermutation
Dim As UInteger n
For n = 1 To 10
superpermutation = superperm(n)
Print Using "### ######## ######## "; n; superpermsize(n); Len(superpermutation);
If n < 5 Then
Print superpermutation
Else
Print
End If
Next
' empty keyboard buffer
While InKey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End

View file

@ -0,0 +1,62 @@
package main
import "fmt"
const max = 12
var (
super []byte
pos int
cnt [max]int
)
// 1! + 2! + ... + n!
func factSum(n int) int {
s := 0
for x, f := 0, 1; x < n; {
x++
f *= x
s += f
}
return s
}
func r(n int) bool {
if n == 0 {
return false
}
c := super[pos-n]
cnt[n]--
if cnt[n] == 0 {
cnt[n] = n
if !r(n - 1) {
return false
}
}
super[pos] = c
pos++
return true
}
func superperm(n int) {
pos = n
le := factSum(n)
super = make([]byte, le)
for i := 0; i <= n; i++ {
cnt[i] = i
}
for i := 1; i <= n; i++ {
super[i-1] = byte(i) + '0'
}
for r(n) {
}
}
func main() {
for n := 0; n < max; n++ {
fmt.Printf("superperm(%2d) ", n)
superperm(n)
fmt.Printf("len = %d\n", len(super))
}
}

View file

@ -0,0 +1,55 @@
import static java.util.stream.IntStream.rangeClosed
class Superpermutation {
final static int nMax = 12
static char[] superperm
static int pos
static int[] count = new int[nMax]
static int factSum(int n) {
return rangeClosed(1, n)
.map({ m -> rangeClosed(1, m).reduce(1, { a, b -> a * b }) }).sum()
}
static boolean r(int n) {
if (n == 0) {
return false
}
char c = superperm[pos - n]
if (--count[n] == 0) {
count[n] = n
if (!r(n - 1)) {
return false
}
}
superperm[pos++] = c
return true
}
static void superPerm(int n) {
String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
pos = n
superperm = new char[factSum(n)]
for (int i = 0; i < n + 1; i++) {
count[i] = i
}
for (int i = 1; i < n + 1; i++) {
superperm[i - 1] = chars.charAt(i)
}
while (r(n)) {
}
}
static void main(String[] args) {
for (int n = 0; n < nMax; n++) {
superPerm(n)
printf("superPerm(%2d) len = %d", n, superperm.length)
println()
}
}
}

View file

@ -0,0 +1,18 @@
approxmin=:3 :0
seqs=. y{~(A.&i.~ !)#y
r=.{.seqs
seqs=.}.seqs
while.#seqs do.
for_n. i.-#y do.
tail=. (-n){. r
b=. tail -:"1 n{."1 seqs
if. 1 e.b do.
j=. b i.1
r=. r, n}.j{seqs
seqs=. (<<<j) { seqs
break.
end.
end.
end.
r
)

View file

@ -0,0 +1,9 @@
(#, #@approxmin)@> (1+i.8) {.&.> <'abcdefghijk'
1 1
2 3
3 9
4 33
5 153
6 873
7 5913
8 46233

View file

@ -0,0 +1,51 @@
import static java.util.stream.IntStream.rangeClosed;
public class Test {
final static int nMax = 12;
static char[] superperm;
static int pos;
static int[] count = new int[nMax];
static int factSum(int n) {
return rangeClosed(1, n)
.map(m -> rangeClosed(1, m).reduce(1, (a, b) -> a * b)).sum();
}
static boolean r(int n) {
if (n == 0)
return false;
char c = superperm[pos - n];
if (--count[n] == 0) {
count[n] = n;
if (!r(n - 1))
return false;
}
superperm[pos++] = c;
return true;
}
static void superPerm(int n) {
String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
pos = n;
superperm = new char[factSum(n)];
for (int i = 0; i < n + 1; i++)
count[i] = i;
for (int i = 1; i < n + 1; i++)
superperm[i - 1] = chars.charAt(i);
while (r(n)) {
}
}
public static void main(String[] args) {
for (int n = 0; n < nMax; n++) {
superPerm(n);
System.out.printf("superPerm(%2d) len = %d", n, superperm.length);
System.out.println();
}
}
}

View file

@ -0,0 +1,40 @@
const nmax = 12
function r!(n, s, pos, count)
if n == 0
return false
end
c = s[pos + 1 - n]
count[n + 1] -= 1
if count[n + 1] == 0
count[n + 1] = n
if r!(n - 1, s, pos, count) == 0
return false
end
end
s[pos + 1] = c
pos += 1
true
end
function superpermutation(n)
count = zeros(nmax)
pos = n
superperm = zeros(UInt8, n < 2 ? n : mapreduce(factorial, +, 1:n))
for i in 0:n-1
count[i + 1] = i
superperm[i + 1] = Char(i + '0')
end
count[n + 1] = n
while r!(n, superperm, pos, count) ; end
superperm
end
function testsuper(N, verbose=false)
for i in 0:N-1
s = superpermutation(i)
println("Superperm($i) has length $(length(s)) ", (verbose ? String(s) : ""))
end
end
testsuper(nmax)

View file

@ -0,0 +1,45 @@
// version 1.1.2
const val MAX = 12
var sp = CharArray(0)
val count = IntArray(MAX)
var pos = 0
fun factSum(n: Int): Int {
var s = 0
var x = 0
var f = 1
while (x < n) {
f *= ++x
s += f
}
return s
}
fun r(n: Int): Boolean {
if (n == 0) return false
val c = sp[pos - n]
if (--count[n] == 0) {
count[n] = n
if (!r(n - 1)) return false
}
sp[pos++] = c
return true
}
fun superPerm(n: Int) {
pos = n
val len = factSum(n)
if (len > 0) sp = CharArray(len)
for (i in 0..n) count[i] = i
for (i in 1..n) sp[i - 1] = '0' + i
while (r(n)) {}
}
fun main(args: Array<String>) {
for (n in 0 until MAX) {
superPerm(n)
println("superPerm(${"%2d".format(n)}) len = ${sp.size}")
}
}

View file

@ -0,0 +1,33 @@
ClearAll[OverlapDistance, ConstructDistances]
OverlapDistance[{s1_List, s2_List}] := OverlapDistance[s1, s2]
OverlapDistance[s1_List, s2_List] := Module[{overlaprange, overlap, l},
overlaprange = {Min[Length[s1], Length[s2]], 0};
l = LengthWhile[Range[Sequence @@ overlaprange, -1], Take[s1, -#] =!= Take[s2, #] &];
overlap = overlaprange[[1]] - l;
<|"Overlap" -> overlap, "Distance" -> Length[s2] - overlap|>
]
ConstructDistances[perms_List] := Module[{sel, OD, fullseq},
OD = BlockMap[OverlapDistance, perms, 2, 1];
fullseq =
Fold[Join[#1, Drop[#2[[2]], #2[[1]]["Overlap"]]] &,
First[perms], {OD, Rest[perms]} // Transpose];
fullseq
]
Dynamic[Length[perms]]
Do[
n = i;
perms = Permutations[Range[n]];
{start, perms} = TakeDrop[perms, 1];
While[Length[perms] > 0,
last = Last[start];
dists =
Table[<|"Index" -> i, OverlapDistance[last, perms[[i]]]|>, {i,
Length[perms]}];
sel = First[TakeSmallestBy[dists, #["Distance"] &, 1]];
AppendTo[start, perms[[sel["Index"]]]];
perms = Delete[perms, sel["Index"]];
];
Print[{n, Length@ConstructDistances[start]}]
,
{i, 1, 7}
]

View file

@ -0,0 +1,44 @@
import strformat
const MAX = 12
var super: seq[char] = @[]
var pos: int
var cnt: array[MAX, int]
proc factSum(n: int): int =
var s, x = 0
var f = 1
while x < n:
inc x
f *= x
inc s, f
s
proc r(n: int): bool =
if n == 0:
return false
var c = super[pos - n]
dec cnt[n]
if cnt[n] == 0:
cnt[n] = n
if not r(n - 1):
return false
super[pos] = c
inc pos
true
proc superperm(n: int) =
pos = n
var le = factSum(n)
super.setLen(le)
for i in 0..n:
cnt[i] = i
for i in 1..n:
super[i-1] = char(i + ord('0'))
while r(n):
discard
for n in 0..<MAX:
write(stdout, fmt"superperm({n:2})")
superperm(n)
writeLine(stdout, fmt" len = {len(super)}")

View file

@ -0,0 +1,65 @@
class SuperPermutation {
@super : static : Char[];
@pos : static : Int;
@cnt : static : Int[];
function : Main(args : String[]) ~ Nil {
max := 12;
@cnt := Int->New[max];
@super := Char->New[0];
for(n := 0; n < max; n += 1;) {
"superperm({$n}) "->Print();
SuperPerm(n);
len := @super->Size() - 1;
"len = {$len}"->PrintLine();
};
}
function : native : FactSum(n : Int) ~ Int {
s := 0; x := 0; f := 1;
while(x < n) {
f *= ++x; s += f;
};
return s;
}
function : native : R(n : Int) ~ Bool {
if(n = 0) {
return false;
};
c := @super[@pos - n];
if(--@cnt[n] = 0) {
@cnt[n] := n;
if(<>R(n - 1)) {
return false;
};
};
@super[@pos++] := c;
return true;
}
function : SuperPerm(n : Int) ~ Nil {
@pos := n;
len := FactSum(n);
tmp := Char->New[len + 1];
Runtime->Copy(tmp, 0, @super, 0, @super->Size());
@super := tmp;
for(i := 0; i <= n; i += 1;) {
@cnt[i] := i;
};
for(i := 1; i <= n; i += 1;) {
@super[i - 1] := i + '0';
};
do {
r := R(n);
}
while(r);
}
}

View file

@ -0,0 +1,10 @@
use ntheory qw/forperm/;
for my $len (1..8) {
my($pre, $post, $t) = ("","");
forperm {
$t = join "",@_;
$post .= $t unless index($post ,$t) >= 0;
$pre = $t . $pre unless index($pre, $t) >= 0;
} $len;
printf "%2d: %8d %8d\n", $len, length($pre), length($post);
}

View file

@ -0,0 +1,60 @@
(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">nMax</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()=</span><span style="color: #004600;">JS</span><span style="color: #0000FF;">?</span><span style="color: #000000;">8</span><span style="color: #0000FF;">:</span><span style="color: #000000;">12</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- Aside: on desktop/Phix, strings can be modified in situ, whereas
-- JavaScript strings are immutable, and the equivalent code
-- in p2js.js ends up doing excessive splitting and splicing
-- hence nMax has to be significantly smaller in a browser.</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">superperm</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">count</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">pos</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">factSum</span><span style="color: #0000FF;">(</span><span style="color: #004080;">int</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">f</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">f</span> <span style="color: #0000FF;">*=</span> <span style="color: #000000;">i</span>
<span style="color: #000000;">s</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">f</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">s</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">(</span><span style="color: #004080;">int</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">n</span> <span style="color: #0000FF;">==</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">superperm</span><span style="color: #0000FF;">[</span><span style="color: #000000;">pos</span><span style="color: #0000FF;">-</span><span style="color: #000000;">n</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">count</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">count</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">count</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">n</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">pos</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">superperm</span><span style="color: #0000FF;">[</span><span style="color: #000000;">pos</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">c</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">true</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">superPerm</span><span style="color: #0000FF;">(</span><span style="color: #004080;">int</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">chars</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">n</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">pos</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">n</span>
<span style="color: #000000;">superperm</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">chars</span><span style="color: #0000FF;">&</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">,</span><span style="color: #000000;">factSum</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">count</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> <span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">superperm</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">""</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">elsif</span> <span style="color: #000000;">n</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">7</span> <span style="color: #008080;">then</span>
<span style="color: #000080;font-style:italic;">-- (I estimate it would take at least 5 days to validate
-- superPerm(12), feel free to try it on your own time)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">factorial</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">match</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">permute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">chars</span><span style="color: #0000FF;">),</span><span style="color: #000000;">superperm</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">nMax</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">superPerm</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">superperm</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">l</span><span style="color: #0000FF;">></span><span style="color: #000000;">40</span> <span style="color: #008080;">then</span> <span style="color: #000000;">superperm</span><span style="color: #0000FF;">[</span><span style="color: #000000;">20</span><span style="color: #0000FF;">..-</span><span style="color: #000000;">20</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"..."</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">e</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">elapsed</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"superPerm(%2d) len = %d %s (%s)\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">l</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">superperm</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">e</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--

View file

@ -0,0 +1,58 @@
(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">factSum</span><span style="color: #0000FF;">(</span><span style="color: #004080;">int</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">f</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">f</span> <span style="color: #0000FF;">*=</span> <span style="color: #000000;">i</span>
<span style="color: #000000;">s</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">f</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">s</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">superPerm</span><span style="color: #0000FF;">(</span><span style="color: #004080;">int</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">chars</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">n</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">f</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">factorial</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">perms</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">f</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">perms</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">permute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">chars</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">perms</span><span style="color: #0000FF;">[$]</span>
<span style="color: #000000;">perms</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">perms</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">while</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">perms</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">best</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">bi</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">perms</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">perms</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">pi</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">perms</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">m</span><span style="color: #0000FF;">],</span><span style="color: #000000;">pi</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">l</span><span style="color: #0000FF;">=</span><span style="color: #000000;">k</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">m</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">pi</span><span style="color: #0000FF;">[</span><span style="color: #000000;">l</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">m</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">></span><span style="color: #000000;">best</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">best</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">k</span>
<span style="color: #000000;">bi</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">match</span><span style="color: #0000FF;">(</span><span style="color: #000000;">perms</span><span style="color: #0000FF;">[</span><span style="color: #000000;">bi</span><span style="color: #0000FF;">],</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #000080;font-style:italic;">-- (sanity check)</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">perms</span><span style="color: #0000FF;">[</span><span style="color: #000000;">bi</span><span style="color: #0000FF;">][</span><span style="color: #000000;">best</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">perms</span><span style="color: #0000FF;">[</span><span style="color: #000000;">bi</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">perms</span><span style="color: #0000FF;">[$]</span>
<span style="color: #000000;">perms</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">perms</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">lr</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">fsn</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">factSum</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">op</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"&lt;"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"="</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"&gt;"</span><span style="color: #0000FF;">}[</span><span style="color: #7060A8;">compare</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lr</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fsn</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">e</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">></span><span style="color: #000000;">1</span><span style="color: #0000FF;">?</span><span style="color: #008000;">", "</span><span style="color: #0000FF;">&</span><span style="color: #7060A8;">elapsed</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">):</span><span style="color: #008000;">""</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"superPerm(%d) len = %d (%s%d%s)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">lr</span><span style="color: #0000FF;">,</span><span style="color: #000000;">op</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fsn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">e</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">7</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- (note: 8 takes 65x longer than 7)</span>
<span style="color: #000000;">superPerm</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--

View file

@ -0,0 +1,40 @@
EnableExplicit
#MAX=10
Declare.i fact_sum(n.i) : Declare.i r(n.i) : Declare superperm(n.i)
Global pos.i, Dim cnt.i(#MAX), Dim super.s{1}(fact_sum(#MAX))
If OpenConsole() ;- MAIN: Superpermutation_minimisation
Define.i n
For n=0 To #MAX
superperm(n) : Print("superperm("+RSet(Str(n),2)+") len = "+LSet(Str(pos),10))
If n<=4 : Print(~"\t"+PeekS(@super(),pos)) : EndIf
PrintN("")
Next
Input()
EndIf
End ;- END: Superpermutation_minimisation
Procedure.i fact_sum(n.i)
Define.i s=0,f=1,x=0
While x<n : x+1 : f*x : s+f : Wend
ProcedureReturn s
EndProcedure
Procedure.i r(n.i)
If Not n : ProcedureReturn 0 : EndIf
Define c.s{1}=super(pos-n)
cnt(n)-1
If Not cnt(n)
cnt(n)=n
If Not r(n-1) : ProcedureReturn 0 : EndIf
EndIf
super(pos)=c : pos+1 : ProcedureReturn 1
EndProcedure
Procedure superperm(n.i)
pos=n
Define.i len=fact_sum(n),i
For i=0 To n : cnt(i)=i : Next
For i=1 To n : super(i-1)=Chr('0'+i) : Next
While r(n) : Wend
EndProcedure

View file

@ -0,0 +1,140 @@
"Generate a short Superpermutation of n characters A... as a string using various algorithms."
from __future__ import print_function, division
from itertools import permutations
from math import factorial
import string
import datetime
import gc
MAXN = 7
def s_perm0(n):
"""
Uses greedy algorithm of adding another char (or two, or three, ...)
until an unseen perm is formed in the last n chars
"""
allchars = string.ascii_uppercase[:n]
allperms = [''.join(p) for p in permutations(allchars)]
sp, tofind = allperms[0], set(allperms[1:])
while tofind:
for skip in range(1, n):
for trial_add in (''.join(p) for p in permutations(sp[-n:][:skip])):
#print(sp, skip, trial_add)
trial_perm = (sp + trial_add)[-n:]
if trial_perm in tofind:
#print(sp, skip, trial_add)
sp += trial_add
tofind.discard(trial_perm)
trial_add = None # Sentinel
break
if trial_add is None:
break
assert all(perm in sp for perm in allperms) # Check it is a superpermutation
return sp
def s_perm1(n):
"""
Uses algorithm of concatenating all perms in order if not already part
of concatenation.
"""
allchars = string.ascii_uppercase[:n]
allperms = [''.join(p) for p in sorted(permutations(allchars))]
perms, sp = allperms[::], ''
while perms:
nxt = perms.pop()
if nxt not in sp:
sp += nxt
assert all(perm in sp for perm in allperms)
return sp
def s_perm2(n):
"""
Uses algorithm of concatenating all perms in order first-last-nextfirst-
nextlast... if not already part of concatenation.
"""
allchars = string.ascii_uppercase[:n]
allperms = [''.join(p) for p in sorted(permutations(allchars))]
perms, sp = allperms[::], ''
while perms:
nxt = perms.pop(0)
if nxt not in sp:
sp += nxt
if perms:
nxt = perms.pop(-1)
if nxt not in sp:
sp += nxt
assert all(perm in sp for perm in allperms)
return sp
def _s_perm3(n, cmp):
"""
Uses algorithm of concatenating all perms in order first,
next_with_LEASTorMOST_chars_in_same_position_as_last_n_chars, ...
"""
allchars = string.ascii_uppercase[:n]
allperms = [''.join(p) for p in sorted(permutations(allchars))]
perms, sp = allperms[::], ''
while perms:
lastn = sp[-n:]
nxt = cmp(perms,
key=lambda pm:
sum((ch1 == ch2) for ch1, ch2 in zip(pm, lastn)))
perms.remove(nxt)
if nxt not in sp:
sp += nxt
assert all(perm in sp for perm in allperms)
return sp
def s_perm3_max(n):
"""
Uses algorithm of concatenating all perms in order first,
next_with_MOST_chars_in_same_position_as_last_n_chars, ...
"""
return _s_perm3(n, max)
def s_perm3_min(n):
"""
Uses algorithm of concatenating all perms in order first,
next_with_LEAST_chars_in_same_position_as_last_n_chars, ...
"""
return _s_perm3(n, min)
longest = [factorial(n) * n for n in range(MAXN + 1)]
weight, runtime = {}, {}
print(__doc__)
for algo in [s_perm0, s_perm1, s_perm2, s_perm3_max, s_perm3_min]:
print('\n###\n### %s\n###' % algo.__name__)
print(algo.__doc__)
weight[algo.__name__], runtime[algo.__name__] = 1, datetime.timedelta(0)
for n in range(1, MAXN + 1):
gc.collect()
gc.disable()
t = datetime.datetime.now()
sp = algo(n)
t = datetime.datetime.now() - t
gc.enable()
runtime[algo.__name__] += t
lensp = len(sp)
wt = (lensp / longest[n]) ** 2
print(' For N=%i: SP length %5i Max: %5i Weight: %5.2f'
% (n, lensp, longest[n], wt))
weight[algo.__name__] *= wt
weight[algo.__name__] **= 1 / n # Geometric mean
weight[algo.__name__] = 1 / weight[algo.__name__]
print('%*s Overall Weight: %5.2f in %.1f seconds.'
% (29, '', weight[algo.__name__], runtime[algo.__name__].total_seconds()))
print('\n###\n### Algorithms ordered by shortest superpermutations first\n###')
print('\n'.join('%12s (%.3f)' % kv for kv in
sorted(weight.items(), key=lambda keyvalue: -keyvalue[1])))
print('\n###\n### Algorithms ordered by shortest runtime first\n###')
print('\n'.join('%12s (%.3f)' % (k, v.total_seconds()) for k, v in
sorted(runtime.items(), key=lambda keyvalue: keyvalue[1])))

View file

@ -0,0 +1,59 @@
from array import array
from string import ascii_uppercase, digits
from operator import mul
try:
import psyco
psyco.full()
except:
pass
N_MAX = 12
# fact_sum(n) = 1! + 2! + ... + n!
def fact_sum(n):
return sum(reduce(mul, xrange(1, m + 1), 1) for m in xrange(1, n + 1))
def r(n, superperm, pos, count):
if not n:
return False
c = superperm[pos - n]
count[n] -= 1
if not count[n]:
count[n] = n
if not r(n - 1, superperm, pos, count):
return False
superperm[pos] = c
pos += 1
return True
def super_perm(n, superperm, pos, count, chars = digits + ascii_uppercase):
assert len(chars) >= N_MAX
pos = n
superperm += array("c", " ") * (fact_sum(n) - len(superperm))
for i in xrange(n + 1):
count[i] = i
for i in xrange(1, n + 1):
superperm[i - 1] = chars[i]
while r(n, superperm, pos, count):
pass
def main():
superperm = array("c", "")
pos = 0
count = array("l", [0]) * N_MAX
for n in xrange(N_MAX):
super_perm(n, superperm, pos, count)
print "Super perm(%2d) len = %d" % (n, len(superperm)),
#print superperm.tostring(),
print
main()

View file

@ -0,0 +1,37 @@
/*REXX program attempts to find better minimizations for computing superpermutations.*/
parse arg cycles . /*obtain optional arguments from the CL*/
if cycles=='' | cycles=="," then cycles= 7 /*Not specified? Then use the default.*/
do n=0 to cycles
#= 0; $.= /*populate the first permutation. */
do pop=1 for n; @.pop= d2x(pop); $.0= $.0 || @.pop
end /*pop*/
do while aPerm(n, 0)
if n\==0 then #= #+1; $.#=
do j=1 for n; $.#= $.# || @.j
end /*j*/
end /*while*/
z= $.0
nm= n-1
do p=1 for #; if $.j=='' then iterate
if pos($.p, z)\==0 then iterate
parse var $.p h 2 R 1 L =(n)
if left(z, nm)==R then do; z= h || z; iterate; end
if right(z, 1)==h then do; z= z || R; iterate; end
z= z || $.p
end /*p*/ /* [↑] more IFs could be added for opt*/
L= commas( length(z) )
say 'length of superpermutation('n") =" right(L, max(length(L), cycles+2) )
end /*cycle*/
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
commas: parse arg ?; do jc=length(?)-3 to 1 by -3; ?=insert(',', ?, jc); end; return ?
/*──────────────────────────────────────────────────────────────────────────────────────*/
aPerm: procedure expose @.; parse arg n,i; nm= n - 1; if n==0 then return 0
do k=nm by -1 for nm; kp=k+1; if @.k<@.kp then do; i=k; leave; end; end /*k*/
do j=i+1 while j<n; parse value @.j @.n with @.n @.j; n= n-1; end /*j*/
if i==0 then return 0
do m=i+1 while @.m<@.i; end /*m*/; parse value @.m @.i with @.i @.m
return 1

View file

@ -0,0 +1,50 @@
/*REXX program attempts to find better minimizations for computing superpermutations.*/
parse arg cycles . /*obtain optional arguments from the CL*/
if cycles=='' | cycles=="," then cycles= 7 /*Not specified? Then use the default.*/
do n=0 to cycles
#= 0; $.= /*populate the first permutation. */
do pop=1 for n; @.pop= d2x(pop); $.0= $.0 || @.pop
end /*pop*/
do while aPerm(n,0); if n\==0 then #= #+1; $.#=
do j=1 for n; $.#= $.# || @.j
end /*j*/
end /*while*/
z= $.0
c= 0 /*count of found permutations (so far).*/
do j=1 while c\==#
if j># then do; c= c + 1 /*exhausted finds and shortcuts; concat*/
z= z || $.j; $.j=
j= 1
end
if $.j=='' then iterate /*Already found? Then ignore this perm.*/
if pos($.j, z)\==0 then do; c= c + 1; $.j=
iterate
end
do k=n-1 to 1 by -1 /*handle the shortcuts in perm finding.*/
if substr($.j, k)==left(z, k) then do; c= c+1 /*found rightish shortcut*/
z= left($.j, k-1) || z; $.j=
iterate j
end
if left($.j, k) ==right(z, k) then do; c= c+1 /*found leftish shortcut*/
z= z || substr($.j, k+1); $.j=
iterate j
end
end /*k*/ /* [↑] more IFs could be added for opt*/
end /*j*/
L= commas( length(z) )
say 'length of superpermutation('n") =" right(L, max(length(L), cycles+2) )
end /*n*/
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
commas: parse arg ?; do jc=length(?)-3 to 1 by -3; ?=insert(',', ?, jc); end; return ?
/*──────────────────────────────────────────────────────────────────────────────────────*/
aPerm: procedure expose @.; parse arg n,i; nm=n-1; if n==0 then return 0
do k=nm by -1 for nm; kp=k+1; if @.k<@.kp then do; i=k;leave; end; end /*k*/
do j=i+1 while j<n; parse value @.j @.n with @.n @.j; n=n-1; end /*j*/
if i==0 then return 0
do m=i+1 while @.m<@.i; end /*m*/; parse value @.m @.i with @.i @.m
return 1

View file

@ -0,0 +1,33 @@
#lang racket/base
(require racket/list racket/format)
(define (index-of1 x l) (for/first ((i (in-naturals 1)) (m (in-list l)) #:when (equal? m x)) i))
(define (sprprm n)
(define n-1 (- n 1))
(define sp:n-1 (superperm n-1))
(let loop ((subs (let loop ((sp sp:n-1) (i (- (length sp:n-1) n-1 -1)) (rv null))
(cond
[(zero? i) (reverse rv)]
[else
(define sub (take sp n-1))
(loop (cdr sp)
(- i 1)
(if (check-duplicates sub) rv (cons sub rv)))])))
(ary null))
(if (null? subs)
ary
(let ((sub (car subs)))
(define i (if (null? ary) 0 (index-of1 (last ary) sub)))
(loop (cdr subs) (append ary (drop sub i) (list n) sub))))))
(define superperm
(let ((hsh (make-hash (list (cons 1 (list 1))))))
(lambda (n) (hash-ref! hsh n (lambda () (sprprm n))))))
(define (20..20 ary)
(if (< (length ary) 41) ary (append (take ary 20) (cons '.. (take-right ary 20)))))
(for* ((n (in-range 1 (add1 8))) (ary (in-value (superperm n))))
(printf "~a: len = ~a : ~a~%" (~a n #:width 3) (~a (length ary) #:width 8) (20..20 ary)))

View file

@ -0,0 +1,9 @@
for 1..8 -> $len {
my $pre = my $post = my $t = '';
for ('a'..'z')[^$len].permutations -> @p {
$t = @p.join('');
$post ~= $t unless index($post, $t);
$pre = $t ~ $pre unless index($pre, $t);
}
printf "%1d: %8d %8d\n", $len, $pre.chars, $post.chars;
}

View file

@ -0,0 +1,22 @@
#A straight forward implementation of N. Johnston's algorithm. I prefer to look at this as 2n+1 where
#the second n is first n reversed, and the 1 is always the second symbol. This algorithm will generate
#just the left half of the result by setting l to [1,2] and looping from 3 to 6. For the purpose of
#this task I am going to start from an empty array and generate the whole strings using just the
#rules.
#
#Nigel Galloway: December 16th., 2014
#
l = []
(1..6).each{|e|
a, i = [], e-2
(0..l.length-e+1).each{|g|
if not (n = l[g..g+e-2]).uniq!
a.concat(n[(a[0]? i : 0)..-1]).push(e).concat(n)
i = e-2
else
i -= 1
end
}
a.each{|n| print n}; puts "\n\n"
l = a
}

View file

@ -0,0 +1,16 @@
def superperm(n)
return [1] if n==1
superperm(n-1).each_cons(n-1).with_object([]) do |sub, ary|
next if sub.uniq!
i = ary.empty? ? 0 : sub.index(ary.last)+1
ary.concat(sub[i..-1] + [n] + sub)
end
end
def to_16(a) a.map{|x| x.to_s(16)}.join end
for n in 1..10
ary = superperm(n)
print "%3d: len =%8d :" % [n, ary.size]
puts n<5 ? ary.join : to_16(ary.first(20)) + "...." + to_16(ary.last(20))
end

View file

@ -0,0 +1,12 @@
object SuperpermutationMinimisation extends App {
val nMax = 12
@annotation.tailrec
def factorial(number: Int, acc: Long = 1): Long =
if (number == 0) acc else factorial(number - 1, acc * number)
def factSum(n: Int): Long = (1 to n).map(factorial(_)).sum
for (n <- 0 until nMax) println(f"superPerm($n%2d) len = ${factSum(n)}%d")
}

View file

@ -0,0 +1,9 @@
for len in (1..8) {
var (pre="", post="")
@^len -> permutations {|*p|
var t = p.join
post.append!(t) if !post.contains(t)
pre.prepend!(t) if !pre.contains(t)
}
printf("%2d: %8d %8d\n", len, pre.len, post.len)
}

View file

@ -0,0 +1,48 @@
import "/fmt" for Fmt
var max = 12
var sp = []
var count = List.filled(max, 0)
var pos = 0
var factSum = Fn.new { |n|
var s = 0
var x = 0
var f = 1
while (x < n) {
x = x + 1
f = f * x
s = s + f
}
return s
}
var r // recursive
r = Fn.new { |n|
if (n == 0) return false
var c = sp[pos - n]
count[n] = count[n] - 1
if (count[n] == 0) {
count[n] = n
if (!r.call(n - 1)) return false
}
sp[pos] = c
pos = pos + 1
return true
}
var superPerm = Fn.new { |n|
pos = n
var len = factSum.call(n)
if (len > 0) sp = List.filled(len, "\0")
for (i in 0..n) count[i] = i
if (n > 0) {
for (i in 1..n) sp[i - 1] = String.fromByte(48 + i)
}
while (r.call(n)) {}
}
for (n in 0...max) {
superPerm.call(n)
Fmt.print("superPerm($2d) len = $d", n, sp.count)
}

View file

@ -0,0 +1,52 @@
include xpllib; \for Print and StrLen
define Maxx = 12;
char Super;
int Pos, Cnt(Maxx);
func FactSum(N); \1! + 2! + ... + n!
int N, S, X, F;
[S:= 0; X:= 0; F:= 1;
while X < N do
[X:= X+1;
F:= F*X;
S:= S+F;
];
return S;
];
func R(N);
int N, C;
[if N = 0 then return false;
C:= Super(Pos - N);
Cnt(N):= Cnt(N)-1;
if Cnt(N) = 0 then
[Cnt(N):= N;
if R(N-1) = 0 then return false;
];
Super(Pos):= C; Pos:= Pos+1;
return true;
];
proc Superperm(N);
int N, I, Len;
[Pos:= N;
Len:= FactSum(N);
Super:= ReallocMem(Super, Len+1);
Super(Len):= 0;
for I:= 0 to N do Cnt(I):= I;
for I:= 1 to N do Super(I-1):= I+^0;
while R(N) do [];
];
int N;
[Super:= 0;
for N:= 0 to Maxx-1 do
[Print("Superperm(%d) ", N);
Superperm(N);
Print("len = %d", StrLen(Super));
\Uncomment next line to see the string itself
\Print(": %s", Super);
CrLf(0);
];
]

View file

@ -0,0 +1,36 @@
const MAX = 12;
var super=Data(), pos, cnt; // global state, ick
fcn fact_sum(n){ // -->1! + 2! + ... + n!
[1..n].reduce(fcn(s,n){ s + [2..n].reduce('*,1) },0)
}
fcn r(n){
if (not n) return(0);
c := super[pos - n];
if (not (cnt[n]-=1)){
cnt[n] = n;
if (not r(n-1)) return(0);
}
super[pos] = c; pos+=1;
1
}
fcn superperm(n){
pos = n;
len := fact_sum(n);
super.fill(0,len); // this is pretty close to recalloc()
cnt = (n+1).pump(List()); //-->(0,1,2,3,..n)
foreach i in (n){ super[i] = i + 0x31; } //-->"1" ... "123456789:;"
while (r(n)){}
}
foreach n in (MAX){
superperm(n);
print("superperm(%2d) len = %d".fmt(n,super.len()));
// uncomment next line to see the string itself
//print(": %s".fmt(super.text));
println();
}