Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
2
Task/Superpermutation-minimisation/00-META.yaml
Normal file
2
Task/Superpermutation-minimisation/00-META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Superpermutation_minimisation
|
||||
27
Task/Superpermutation-minimisation/00-TASK.txt
Normal file
27
Task/Superpermutation-minimisation/00-TASK.txt
Normal 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>
|
||||
|
||||
|
|
@ -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))
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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.
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
)
|
||||
|
|
@ -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
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
@ -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}")
|
||||
}
|
||||
}
|
||||
|
|
@ -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}
|
||||
]
|
||||
|
|
@ -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)}")
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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>
|
||||
<!--
|
||||
|
|
@ -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;">"<"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"="</span><span style="color: #0000FF;">,</span><span style="color: #008000;">">"</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>
|
||||
<!--
|
||||
|
|
@ -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
|
||||
|
|
@ -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])))
|
||||
|
|
@ -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()
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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)))
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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")
|
||||
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -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);
|
||||
];
|
||||
]
|
||||
|
|
@ -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();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue