The **combinatorial calculus** studies the *groupings* that can be obtained with a given number *n* of objects arranged on a given number *k* of places.

The groupings can be formed *without repetitions *or *with repetitions* of the *n* objects.

According to Wikipedia: *Factorial of a positive integer n, denoted by n! is the product of all positive integers less than or equal to n*.

You can calculate factorials with the following formula:

\(n! = n \times \left( {n – 1} \right) \times \ldots \times 2 \times 1 = \prod\limits_{i = 1}^n i \)

Now you might be wondering how you would go about calculating factorials in Python. While I’m certain in the existence of out-of-the-box functions in various libraries, it’s *really easy to define your own function*, and that’s exactly what we’ll do.

Here’s a simple recursive function which will get the job done:

```
def factorial(n):
if n == 1: return 1
else: return n * factorial(n-1)
```

In mathematics, a **permutation** of a set is, loosely speaking, an arrangement of its members into a sequence or linear order, or if the set is already ordered, a rearrangement of its elements. The word “permutation” also refers to the act or process of changing the linear order of an ordered set. In other words, they are *the groupings made when the number of objects equals the number of places and counts the order in which they are arranged*. Permutations can be without repetitions of objects or with repetition of objects. In particular, we will talk about **permutations** if the number of objects corresponds to the number of places; if the number of objects is different from the number of places, we will speak of **dispositions** instead.

A **combination** is a selection of items from a collection, such that (unlike permutations) the order of selection does not matter.

Let’s work this out with an example.

You have a website on which users can register. They need to provide a password that needs to be exactly 8 characters long, and characters **cannot **repeat. We first need to determine how many characters and digits there are in the English alphabet:

- the number of letters: 26
- the number of digits: 10

Which is 36 in total. So ** n = 36**.

**would then be**

*r***, because the password needs to be 8 characters long. Once we know that, it’s easy to calculate the number of unique passwords, given the following formula:**

*8*\(D_{n,k}=\frac{{n!}}{{\left( {n – r} \right)!}}\)

If you went ahead and calculated by hand:

\(\frac{{36!}}{{\left( {36 – 8} \right)!}} = 1220096908800\)

Or even in Python, it really is a trivial task:

```
def factorial(n):
if n == 1: return 1
else: return n * factorial(n-1)
def disposition_without_repetition(n,r):
return (factorial(n) / factorial(n-r))
m= disposition_without_repetition(36, 8)
print(m)
```

** Okay, cool, but I want to allow my users to repeat characters.** No problem, in that case, we’re talking about dispositions with repetition, and the formula is even simpler:

\(D_{n,k}^r = {n^k}\)

You already know what **n** is *36*, and what **r** is *8*, so here’s the solution:

```
def factorial(n):
if n == 1: return 1
else: return n * factorial(n-1)
def disposition_without_repetition(n,r):
return (factorial(n) / factorial(n-r))
def disposition_with_repetition(n,r):
return n ** r
m= disposition_with_repetition(36, 8)
print(m)
```

or:

\(D_{36,8}^r=36^8=2821109907456\)

That’s a whole lot of password options.

How many anagrams, even without meaning, can be formed with the word “MAMMA”?

In this case, the **order counts**, but the five letters **are not all distinct**: *M* is repeated 3 times; *A* is repeated 2 times.

\(P_n^r = \frac{{5!}}{{3! \cdot {2_2}!}} = \frac{{120}}{{6 \cdot 2}} = 10\)

or, in different words, there are 10 words that can be formed with the letters of the word MAMMA.

Now, consider the following sentence: **A group of people selected for a team is the same group, the order doesn’t matter.** That’s the whole idea behind **combinations**. If you select 5 members for the team, you could order them by name, height, or something else, but essentially you would still have the same team — ordering is irrelevant.

So, let’s formalize this idea with a formula. The number of combinations ** C** of a set of

**objects taken**

*n***at a time is calculated as follows:**

*r*\(\boldsymbol{C}(\boldsymbol{n}, \boldsymbol{r})=\frac{\boldsymbol{n} !}{\boldsymbol{r} !(\boldsymbol{n}-\boldsymbol{r}) !}\)

Now you can take that equation and solve the following task: *On how many ways can you choose 5 people from a group of 10 for a football team?*

The group would be the same, no matter the ordering. So let’s see, ** n** would be equal to

**, and**

*10***would be**

*r***:**

*5*\(C\left( {10,5} \right) = \frac{{10!}}{{5!\left( {10 – 5} \right)!}} = 252\)

This can once again be easily done with Python:

```
def factorial(n):
if n == 1: return 1
else: return n * factorial(n-1)
def disposition_without_repetition(n,r):
return (factorial(n) / factorial(n-r))
def disposition_with_repetition(n,r):
return n ** r
def combinations_without_repetition(n,r):
return (factorial(n)/(factorial(r) * (factorial(n-r))))
m= combinations_without_repetition(36, 8)
print(m)
```

Great! But now you might be wondering if there exists a version of **combinations which allows repetition**. The answer is yes. I’ll explain now.

Assigned two droppers, the first contains 5 drops of white color and the second 5 drops of black color. By mixing 5 drops chosen between the two, how many different colors can be formed?

Answer:

\(C_{2,5}^r = \frac{{\left( {2 + 5 – 1} \right)!}}{{5!\left( {2 – 1} \right)!}} = \frac{{6!}}{{5! \cdot 1!}} = 6\)

```
def factorial(n):
if n == 1: return 1
else: return n * factorial(n-1)
def disposition_without_repetition(n,r):
return (factorial(n) / factorial(n-r))
def disposition_with_repetition(n,r):
return n ** r
def combinations_without_repetition(n,r):
return (factorial(n)/(factorial(r) * (factorial(n-r))))
def combinations_with_repetition(n,r):
return ((factorial(n+r-1))/(factorial(r)*(factorial(n-1))))
m= combinations_with_repetition(2, 5)
print(m)
```