[Tutor] A small math puzzle [recreational Python]

Kirby Urner urnerk@qwest.net
Sat, 05 Jan 2002 16:05:38 -0800


I sent the following post to sci.math, in case a guru
over there has an answer (googling didn't turn up
anything -- lots of postscript files with buried
treasure).

===============

I am aware of the expression for the number of
derangements of n distinct elements:

d(n) = !n = n![1/0! - 1/1! + 1/2! ... (-1)^n/n!]

where the bracketed expression approaches 1/e
as n->infinity.

What I haven't been able to find, let alone derive,
is an expression that works for multisets, e.g.
all the permutations d(n) of DEADBEEF where no
letter is where it was (EAFEDDBE would be one of
them but EAEEDDBF wouldn't be).

By rearrangement (A B F D D E E E) would give me
coefficients C = [1,1,1,2,3].  len(C) would be the
number of distinct characters while \sigma C[i]
i = 1...len(C) would be the number of elements in
the bag.

So I guess what I'm looking for is some expression
or algorithm that accepts arguments C and returns
the number of derangements.

I find that GAP (Groups, Algorithms and Programming)
will enumerate derangements of bags, as per the examples
below:

  gap> Derangements( [1,1,2,2,3,3] );
  [ [ 2, 2, 3, 3, 1, 1 ], [ 2, 3, 1, 3, 1, 2 ], [ 2, 3, 1, 3, 2, 1 ],
    [ 2, 3, 3, 1, 1, 2 ], [ 2, 3, 3, 1, 2, 1 ], [ 3, 2, 1, 3, 1, 2 ],
    [ 3, 2, 1, 3, 2, 1 ], [ 3, 2, 3, 1, 1, 2 ], [ 3, 2, 3, 1, 2, 1 ],
    [ 3, 3, 1, 1, 2, 2 ] ]
  gap> NrDerangements( [1,2,2,3,3,3,4,4,4,4] );
  338

I'm wondering if NrDerangements is doing something more than
a brute force count of derangements it generates.

Kirby