RosettaCodeData/Task/Superpermutation-minimisation/Python/superpermutation-minimisati...

60 lines
1.2 KiB
Python

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()