# Pre-determining the count of permutations

I have an algorithm in code working for a string permutation. For example, for the character set of 'A', 'A', 'B', 'C', it generates 12 permutations of the string which is equivalent to 4! / 2!. When I allow repetitions within that algorithm, it produces 256 for the following character set: 'A', 'D', 'B', 'C' which is equivalent to 4^4.

Finally, I can also control the length. For example for 'A', 'B', 'C', 'D', 'E', 'F' character set, it can generate 6! / (6-2)! permutations.

However, I am having problems pre-determining how many permutations will be generated when the string length of characters is less than the count of characters within the character set and the character set contains duplicates. For example:

• The character set: 'A', 'A', 'C', 'D', 'E', 'F'
• Length: 3

I can run the algorithm and see that the result is 72 with the below permutations:

 AAC, AAD, AAE, AAF, ACA, ACD, ACE, ACF, ADA, ADC, ADE, ADF, AEA, AEC, AED, AEF, AFA, AFC, AFD, AFE, CAA, CAD, CAE, CAF, CDA, CDE, CDF, CEA, CED, CEF, CFA, CFD, CFE, DAA, DAC, DAE, DAF, DCA, DCE, DCF, DEA, DEC, DEF, DFA, DFC, DFE, EAA, EAC, EAD, EAF, ECA, ECD, ECF, EDA, EDC, EDF, EFA, EFC, EFD, FAA, FAC, FAD, FAE, FCA, FCD, FCE, FDA, FDC, FDE, FEA, FEC, FED 

Does anyone know what the formula is here to reach to 72?

In this case not all elements are regarded, the order matters and no repetition is allowed (The double A case can be considered later). Here you have variation without repetition. The formula is

$V_{n,k}=\binom{n}{k}\cdot k!$

You have $n=5$ and $k=3$. Here the elements are $A,C,D,E,F$. Thus

$V_{n,k}=\binom{5}{3}\cdot 3!=10\cdot 6=60$

Now you consider the double A´s: $AAX$

$X$ can take the letters $C,D,E,F$ ($4$ elements). The three elements can be ordered in three ways, because $X$ can be on the first, second or third place. Therefore the number of arranging $AAX$ is $3\cdot 4=12$. The sum of both results gives $72$.

• thanks! One question: for $V_{n,k}=\binom{5}{3}\cdot 3!=10\cdot 6=60$, how did you get the 10 there? Feb 6 '17 at 8:41
• Feb 6 '17 at 9:00
• @tugberk That´s nice. Two simplification can be made, because some factors can be cancelled. They make the calculation more simple: Firstly $\binom{n}{k}=\binom{n}{n-k}$. For $n=5$ and $k=3$ we get $\binom{5}{5-3}=\binom{5}2$. And secondly $\binom{n}{k}=\frac{n\times (n-1)\times \ldots\times (n-k+1)}{1\times 2\times \ldots \times k}$. For $n=5$ and $k=2$ we finally get $\binom{5}{2}=\frac{5\cdot 4 }{1\cdot 2}=10$. Feb 6 '17 at 14:13

Let your multiset have multiplicities $q_k$ where $1\le k\le m$ and $m$ is the number of types of different letters and let $p=\sum_{k=1}^m q_k.$ We assign slots to each type of letter where the letter may receive between zero and $q_k$ slots. To get the answer we extract the value for $n$ slots supposing that $n$ is the length of the selection that we were given. This gives the combinatorial species

$$\mathfrak{P}_{0\le\cdot\le q_1}(\mathcal{Z}) \mathfrak{P}_{0\le\cdot\le q_2}(\mathcal{Z}) \times \cdots \times \mathfrak{P}_{0\le\cdot\le q_m}(\mathcal{Z}).$$

which produces the formula

$$n! [z^n] \prod_{k=1}^m \left(1+z+\frac{z^2}{2}+\frac{z^3}{6} + \cdots + \frac{z^{q_k}}{q_k!}\right).$$

Compare to the naive method of sieving all combinations which is exponential. The order of terms here is $p$ as opposed to $m^n.$

The Maple code follows which implements enumeration as well as count by formula.

with(combinat);

X :=
proc(L, n)
option remember;

nops([seq(seq(el, el in permute(ch)),
ch in choose(L, n))]);
end;

F :=
proc(L, n)
option remember;
local gf, mset;

mset := convert(L, multiset);
gf := mul(add(z^p/p!, p=0..op(2, mset[q])),
q=1..nops(mset));

n!*coeff(expand(gf), z, n);
end;


Here we see Maple allocate memory as we try to solve a more difficult problem instance and then calculate the answer instantly by using the formula.

> X([seq(seq(A[q], p=1..q), q=1..5)], 10);
memory used=875.4MB, alloc=40.3MB, time=149.99
memory used=880.4MB, alloc=40.8MB, time=150.11
memory used=904.8MB, alloc=56.1MB, time=150.65
memory used=918.1MB, alloc=344.1MB, time=151.50
memory used=952.2MB, alloc=344.1MB, time=152.78
memory used=999.7MB, alloc=376.1MB, time=154.76
memory used=1070.6MB, alloc=408.1MB, time=157.63
memory used=1119.7MB, alloc=408.1MB, time=160.38
memory used=1202.1MB, alloc=440.1MB, time=164.15
memory used=1300.9MB, alloc=472.1MB, time=168.99
memory used=1407.6MB, alloc=504.1MB, time=174.97
1373820

> F([seq(seq(A[q], p=1..q), q=1..5)], 10);
1373820


For the question posed by the OP we get

> F([A,A,C,D,E,F], 3);
72

> X([A,A,C,D,E,F], 3);
72