60 lines
1.2 KiB
Python
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()
|