This scales more like linearly and doesn't seem to be slower
on shorter lists. I think it's better than the first one
I posted.
SignaturePermutation(inp) := block(
[ n:length(inp), k, visited , p, knext, L, sgn:1],
visited : make_array(any,n),
p : make_array(any,n),
fillarray(p,inp),
for k : 0 thru n-1 do (
if not visited[k] then (
knext : k,
L : 0,
while not visited[knext] do (
L : L + 1,
visited[knext] : true,
knext : p[knext]-1 ),
if evenp(L) then sgn : -sgn )),
sgn);
-- John Lapeyre