Skip to content
The Lumenary
Grades 9–12Ages 14–18 75 min

Combinatorics

Choosing, arranging and guaranteeing — binomial coefficients, Pascal's triangle, the binomial theorem, the pigeonhole principle and inclusion–exclusion, proved by counting the same thing in two ways.

Formally verified · 15 LeanComputationally tested · 2 PythonAI-drafted · awaiting human reviewMathematically reviewed: Awaiting human review

Your guides: Chloe, Margaret, Gideon

MotivationH

Three questions

Choosing. A cricket coach in Lahore has a squad of 1515 and must name a team of 1111. How many different teams are possible? Listing them is hopeless — but, as we will see, the answer is exactly 13651365, and it can be found in a few seconds.

Expanding. Multiply out (x+y)5(x + y)^5. You could grind through five brackets — or notice that the coefficients 1,5,10,10,5,11, 5, 10, 10, 5, 1 are already written in a triangle of numbers that was known in India, Persia, North Africa and China centuries before Blaise Pascal wrote about it — though in English it carries his name, Pascal's triangle.

Guaranteeing. In any group of 1313 people, two were born in the same month. Not "probably" — certainly. Yet the argument does not tell us which two.

These are the three faces of combinatorics, the mathematics of finite arrangements: counting exactly, recognising the same count in different disguises, and proving that something must exist. Its favourite method is to count the same set in two different ways — and then the two answers must agree.

IntuitionH

When does order matter?

From five friends — Amina, Bao, Carlos, Divya and Emeka — we choose two.

If we are choosing a captain and a vice-captain, order matters: (Amina, Bao) is different from (Bao, Amina). There are 55 choices for the captain and then 44 for the vice-captain, so 5×4=205 \times 4 = 20 ordered pairs, by the multiplication principle from counting principles.

If we are choosing two people to carry the drinks, order does not matter: {Amina,Bao}\{\text{Amina}, \text{Bao}\} is one pair, however we list it. Each unordered pair appears twice among the 2020 ordered pairs, so there are 20/2=1020 / 2 = 10 unordered pairs:

{A,B},{A,C},{A,D},{A,E},{B,C},{B,D},{B,E},{C,D},{C,E},{D,E}.\begin{aligned} &\{A, B\}, \{A, C\}, \{A, D\}, \{A, E\}, \{B, C\},\\ &\{B, D\}, \{B, E\}, \{C, D\}, \{C, E\}, \{D, E\}. \end{aligned}

This is the division principle: if a list counts every object of interest exactly mm times, divide by mm. Choosing 33 of the 55, there are 5×4×3=605 \times 4 \times 3 = 60 ordered lists, and each set of three appears in 3!=63! = 6 orders, so there are 60/6=1060 / 6 = 10 sets of three.

DefinitionsH

Definitions

Recall n!=n×(n−1)×⋯×2×1n! = n \times (n - 1) \times \cdots \times 2 \times 1, with 0!=10! = 1, and that the number of ordered selections of kk different objects from nn is n(n−1)⋯(n−k+1)=n!(n−k)!n(n - 1)\cdots(n - k + 1) = \dfrac{n!}{(n - k)!}.

Definition— binomial coefficient

For whole numbers nn and kk, the binomial coefficient (nk)\binom{n}{k}, read "nn choose kk", is the number of kk-element subsets of an nn-element set. In particular (nk)=0\binom{n}{k} = 0 when k>nk > n (there are no such subsets), and (n0)=(nn)=1\binom{n}{0} = \binom{n}{n} = 1.

So (52)=10\binom{5}{2} = 10 by the list above. Notice that the definition is a counting definition; the formula comes next, as a theorem.

Definition— pigeonhole principle

If more than nn objects are placed in nn boxes, then some box contains at least two objects.

Definition— inclusion–exclusion (two sets)

For finite sets AA and BB:   ∣A∪B∣=∣A∣+∣B∣−∣A∩B∣\;|A \cup B| = |A| + |B| - |A \cap B|.

Here ∣A∣|A| is the number of elements of AA, as in the lesson on sets. The pigeonhole principle and inclusion–exclusion are both proved below.

Worked examplesH

Worked examples

Example— The cricket team

Choosing the 1111 players who play is the same as choosing the 44 who sit out, so the number of teams is (1511)=(154)=15×14×13×124×3×2×1=1365\binom{15}{11} = \binom{15}{4} = \dfrac{15 \times 14 \times 13 \times 12}{4 \times 3 \times 2 \times 1} = 1365.

Example— Routes through a grid

In a city laid out in blocks, a courier cycles from a corner to the corner 44 blocks east and 33 blocks north, always heading east or north. Every route is a word of 77 letters with 44 E's and 33 N's, such as ENNEENE. A route is decided by which 33 of the 77 steps are north, so there are (73)=35\binom{7}{3} = 35 routes.

Example— Card hands

  • A five-card hand from a pack of 5252 is a 55-element subset: there are (525)=2 598 960\binom{52}{5} = 2\,598\,960 hands.
  • A full house (three cards of one rank, two of another): choose the rank of the three (1313 ways), which three suits ((43)=4\binom{4}{3} = 4), the rank of the pair (1212 ways), and which two suits ((42)=6\binom{4}{2} = 6). Multiplication principle: 13×4×12×6=374413 \times 4 \times 12 \times 6 = 3744 hands.
  • Hands with at least one ace: count the complement. Hands with no ace choose all 55 cards from the 4848 others, so the answer is (525)−(485)=2 598 960−1 712 304=886 656\binom{52}{5} - \binom{48}{5} = 2\,598\,960 - 1\,712\,304 = 886\,656.

Example— A word with repeated letters

How many different arrangements are there of the letters of BANANA? If the six letters were all different there would be 6!=7206! = 720. But swapping the three A's among themselves (3!=63! = 6 ways) or the two N's (2!=22! = 2 ways) gives the same word. Each word is counted 6×2=126 \times 2 = 12 times, so there are 720/12=60720 / 12 = 60 words.

Example— A non-example: overcounting

"Hands with at least one ace: choose an ace (44 ways), then any 44 of the other 5151 cards: 4×(514)=999 6004 \times \binom{51}{4} = 999\,600." This is wrong — it is larger than the correct 886 656886\,656. A hand with two aces, say the ace of hearts and the ace of spades, is counted twice: once when the hearts ace is "the chosen ace" and once when the spades ace is. Every counting argument must produce each object exactly once (or exactly mm times, and then we divide).

ProofH

Theorems, proved by counting

Theorem— Theorem 1 (the factorial formula)

For 0≤k≤n0 \le k \le n: (nk)=n!k! (n−k)!\displaystyle \binom{n}{k} = \frac{n!}{k!\,(n - k)!}.

Proof

Count the ordered selections of kk different objects from nn in two ways. Directly, there are n!(n−k)!\dfrac{n!}{(n - k)!} of them. Alternatively, first choose the set of kk objects ((nk)\binom{n}{k} ways) and then put it in order (k!k! ways): so there are (nk)⋅k!\binom{n}{k} \cdot k! of them. Hence (nk)⋅k!=n!(n−k)!\binom{n}{k} \cdot k! = \dfrac{n!}{(n - k)!}; divide by k!k!.

∎

Theorem— Theorem 2 (symmetry)

For 0≤k≤n0 \le k \le n: (nk)=(nn−k)\displaystyle \binom{n}{k} = \binom{n}{n - k}.

Proof

Sending each kk-element subset SS of an nn-element set XX to its complement X∖SX \setminus S, which has n−kn - k elements, is a one-to-one correspondence: it is its own inverse, since the complement of the complement is SS again. So the two collections have the same size.

∎

Theorem— Theorem 3 (Pascal's rule)

For n≥1n \ge 1 and k≥1k \ge 1: (nk)=(n−1k−1)+(n−1k)\displaystyle \binom{n}{k} = \binom{n - 1}{k - 1} + \binom{n - 1}{k}.

Proof

Count the kk-person committees chosen from nn people, one of whom is Amina. Every committee either contains Amina or it does not, and not both.

  • Committees containing Amina: removing her leaves k−1k - 1 members chosen from the other n−1n - 1 people, and putting her back undoes this. So there are (n−1k−1)\binom{n - 1}{k - 1} of them.
  • Committees not containing Amina: all kk members come from the other n−1n - 1 people. There are (n−1k)\binom{n - 1}{k} of them.

Adding the two disjoint kinds counts every committee exactly once.

∎

Pascal's rule says that each entry of the triangle is the sum of the two entries above it. Starting from the 11s down the edges, it generates all the binomial coefficients without a single multiplication.

111121133114115105116152015614610
Rows $0$ to $6$ of Pascal's triangle. Row $n$ lists $\binom{n}{0}, \binom{n}{1}, \dots, \binom{n}{n}$. Highlighted: Pascal's rule $\binom{5}{2} = \binom{4}{1} + \binom{4}{2}$, that is $10 = 4 + 6$.

Theorem— Theorem 4 (the binomial theorem)

For every whole number nn and all numbers x,yx, y:

(x+y)n=∑k=0n(nk)xkyn−k=yn+(n1)xyn−1+(n2)x2yn−2+⋯+xn.(x + y)^n = \sum_{k=0}^{n} \binom{n}{k} x^k y^{n-k} = y^n + \binom{n}{1} x y^{n-1} + \binom{n}{2} x^2 y^{n-2} + \cdots + x^n.

Proof

Write (x+y)n=(x+y)(x+y)⋯(x+y)(x + y)^n = (x + y)(x + y)\cdots(x + y) with nn brackets. Multiplying out, we get one term for each way of choosing either xx or yy from every bracket, and the term is the product of the choices. A choice that takes xx from exactly kk brackets (and yy from the other n−kn - k) gives xkyn−kx^k y^{n-k}. The number of such choices is the number of ways to pick which kk of the nn brackets supply an xx: that is (nk)\binom{n}{k}. Collecting equal terms (multiplication of numbers is commutative) gives the formula.

∎

There is also a proof by induction on nn, which is the one Lean checks below for (1+x)n(1 + x)^n: multiply (1+x)n=∑k(nk)xk(1 + x)^n = \sum_k \binom{n}{k} x^k by 1+x1 + x, and the coefficient of xk+1x^{k+1} in the product is (nk+1)+(nk)\binom{n}{k+1} + \binom{n}{k} — which is (n+1k+1)\binom{n+1}{k+1} by Pascal's rule. The induction proof and the counting proof are two views of the same fact, which links this lesson to proof by induction and to polynomials.

Example— Using the theorem

(2x−1)4=∑k(4k)(2x)k(−1)4−k=16x4−32x3+24x2−8x+1(2x - 1)^4 = \sum_k \binom{4}{k} (2x)^k (-1)^{4-k} = 16x^4 - 32x^3 + 24x^2 - 8x + 1. Check: putting x=1x = 1 gives 1=16−32+24−8+11 = 16 - 32 + 24 - 8 + 1.

Theorem— Corollary 5 (row sums)

For every nn: ∑k=0n(nk)=2n\displaystyle \sum_{k=0}^{n} \binom{n}{k} = 2^n, and for n≥1n \ge 1: ∑k=0n(−1)k(nk)=0\displaystyle \sum_{k=0}^{n} (-1)^k \binom{n}{k} = 0.

Proof

Put x=y=1x = y = 1 in the binomial theorem for the first identity, and x=−1x = -1, y=1y = 1 for the second: (1+1)n=2n(1 + 1)^n = 2^n and (−1+1)n=0n=0(-1 + 1)^n = 0^n = 0 when n≥1n \ge 1.

A counting proof of the first: both sides count all subsets of an nn-element set. On the left, they are sorted by size; on the right, each of the nn elements is either in or out — 2n2^n possibilities. The second identity says that a non-empty set has as many subsets of even size as of odd size.

∎

The pigeonhole principle

Theorem— Theorem 6 (pigeonhole principle)

If more than nn objects are placed in nn boxes, some box contains at least two objects. More generally, if mm objects are placed in nn boxes, some box contains at least ⌈m/n⌉\lceil m/n \rceil objects.

Proof

Suppose instead that every box contained at most ⌈m/n⌉−1\lceil m/n \rceil - 1 objects. Since ⌈m/n⌉−1<m/n\lceil m/n \rceil - 1 < m/n, the total number of objects would be less than n⋅mn=mn \cdot \dfrac{m}{n} = m — a contradiction. With m>nm > n we have ⌈m/n⌉≥2\lceil m/n \rceil \ge 2, which is the first statement.

∎

The principle is almost too obvious to state — its power lies in choosing the objects and the boxes cleverly.

Example— Birth months

1313 people, 1212 months as boxes: two people share a birth month.

Example— Remainders

Among any n+1n + 1 integers, two differ by a multiple of nn. Boxes: the nn possible remainders 0,1,…,n−10, 1, \dots, n - 1 on division by nn. Two of the n+1n + 1 integers land in the same box, and two numbers with the same remainder differ by a multiple of nn.

Example— Points in a square

Place 55 points anywhere in a square of side 22. Then some two are at distance at most 2\sqrt{2}. Boxes: cut the square into four unit squares (a point on a dividing line goes into either neighbouring square). Two points share a unit square, and no two points of a unit square are further apart than its diagonal, 2\sqrt{2}.

Example— Acquaintances at a party

At any gathering of n≥2n \ge 2 people, two of them have the same number of acquaintances present (acquaintance being mutual). Each person knows between 00 and n−1n - 1 others: nn possible numbers. But 00 and n−1n - 1 cannot both occur — if someone knows everybody, nobody knows nobody. So the nn people have at most n−1n - 1 possible numbers between them, and two share a number. (In the language of graphs: every finite simple graph with at least two vertices has two vertices of the same degree.)

Inclusion–exclusion

Theorem— Theorem 7 (inclusion–exclusion for two and three sets)

For finite sets AA, BB, CC:

∣A∪B∣=∣A∣+∣B∣−∣A∩B∣,|A \cup B| = |A| + |B| - |A \cap B|,∣A∪B∪C∣=∣A∣+∣B∣+∣C∣−∣A∩B∣−∣A∩C∣−∣B∩C∣+∣A∩B∩C∣.|A \cup B \cup C| = |A| + |B| + |C| - |A \cap B| - |A \cap C| - |B \cap C| + |A \cap B \cap C|.

Proof

Two sets. ∣A∣+∣B∣|A| + |B| counts every element of A∪BA \cup B once, except the elements of A∩BA \cap B, which are counted twice; subtracting ∣A∩B∣|A \cap B| corrects this.

Three sets. Apply the two-set rule to A∪BA \cup B and CC: ∣A∪B∪C∣=∣A∪B∣+∣C∣−∣(A∪B)∩C∣|A \cup B \cup C| = |A \cup B| + |C| - |(A \cup B) \cap C|. Now ∣A∪B∣=∣A∣+∣B∣−∣A∩B∣|A \cup B| = |A| + |B| - |A \cap B|, and (A∪B)∩C=(A∩C)∪(B∩C)(A \cup B) \cap C = (A \cap C) \cup (B \cap C), whose size by the two-set rule is ∣A∩C∣+∣B∩C∣−∣A∩B∩C∣|A \cap C| + |B \cap C| - |A \cap B \cap C|, because (A∩C)∩(B∩C)=A∩B∩C(A \cap C) \cap (B \cap C) = A \cap B \cap C. Substituting gives the formula.

∎

Example— Divisible by 2, 3 or 5

How many of 1,2,…,1001, 2, \dots, 100 are divisible by 22, 33 or 55? Let AdA_d be the multiples of dd; then ∣Ad∣=⌊100/d⌋|A_d| = \lfloor 100/d \rfloor and, for instance, A2∩A3=A6A_2 \cap A_3 = A_6. So the answer is

50+33+20−16−10−6+3=74.50 + 33 + 20 - 16 - 10 - 6 + 3 = 74.

The same pattern works for any number of sets: add the sizes of the sets, subtract the sizes of all pairwise intersections, add all triple intersections, and so on, with alternating signs. Here is why — and the binomial theorem returns to help.

Theorem— Theorem 8 (inclusion–exclusion, general)

For finite sets A1,…,AnA_1, \dots, A_n,

∣A1∪⋯∪An∣=∑∅≠S⊆{1,…,n}(−1)∣S∣+1∣⋂i∈SAi∣.|A_1 \cup \cdots \cup A_n| = \sum_{\varnothing \ne S \subseteq \{1, \dots, n\}} (-1)^{|S|+1} \Big| \bigcap_{i \in S} A_i \Big|.

Proof

Take an element xx that lies in exactly m≥1m \ge 1 of the sets. It is counted in ∣⋂i∈SAi∣\big|\bigcap_{i \in S} A_i\big| exactly when SS is a non-empty set of indices of sets containing xx, and there are (mk)\binom{m}{k} such SS of size kk. So the right-hand side counts xx exactly

∑k=1m(−1)k+1(mk)=1−∑k=0m(−1)k(mk)=1−0=1\sum_{k=1}^{m} (-1)^{k+1} \binom{m}{k} = 1 - \sum_{k=0}^{m} (-1)^{k} \binom{m}{k} = 1 - 0 = 1

time, by the alternating row sum (Corollary 5). An element in none of the sets is counted 00 times on both sides.

∎

Example— Derangements: the hat-check problem

Guests at a wedding in Addis Ababa leave nn hats at the door, and the hats are handed back at random. In how many of the n!n! ways does nobody get their own hat? Such an arrangement is a derangement; call their number DnD_n.

Let AiA_i be the arrangements in which guest ii gets the right hat. If the guests in a set SS of size kk all get their own hats, the other n−kn - k hats can be arranged in (n−k)!(n - k)! ways, and there are (nk)\binom{n}{k} sets SS of size kk. By inclusion–exclusion,

∣A1∪⋯∪An∣=∑k=1n(−1)k+1(nk)(n−k)!=∑k=1n(−1)k+1n!k!,|A_1 \cup \cdots \cup A_n| = \sum_{k=1}^{n} (-1)^{k+1} \binom{n}{k} (n - k)! = \sum_{k=1}^{n} (-1)^{k+1} \frac{n!}{k!},

and Dn=n!−∣A1∪⋯∪An∣D_n = n! - |A_1 \cup \cdots \cup A_n|, so

Dn=n!(1−11!+12!−13!+⋯+(−1)nn!).D_n = n! \left( 1 - \frac{1}{1!} + \frac{1}{2!} - \frac{1}{3!} + \cdots + \frac{(-1)^n}{n!} \right).

For example D4=24(1−1+12−16+124)=9D_4 = 24 \left(1 - 1 + \tfrac12 - \tfrac16 + \tfrac{1}{24}\right) = 9. The bracket is a partial sum of the series ∑k(−1)k/k!\sum_k (-1)^k / k!, which (as you may learn with sequences and series) converges to 1/e≈0.36791/e \approx 0.3679, and very quickly: with eight or more guests, the fraction of arrangements that are derangements is 0.36790.3679 to four decimal places.

Formal mathematicsF

The proofs, checked by Lean

In Mathlib, Finset.powersetCard k s is the finite set of kk-element subsets of s, #s is the number of elements of s, and Nat.choose n k is (nk)\binom{n}{k}. Interestingly, Mathlib defines Nat.choose by Pascal's rule — (n0)=1\binom{n}{0} = 1, (0k+1)=0\binom{0}{k+1} = 0, (n+1k+1)=(nk)+(nk+1)\binom{n+1}{k+1} = \binom{n}{k} + \binom{n}{k+1} — so our counting definition becomes a theorem. First, Pascal's rule for subsets, proved exactly like the committee argument (avoid aa, or contain aa):

pascal_subsetsLean 4Proved here from basic factsFormally verified
/-- **Pascal's rule, by counting.** Let `a` be a new element, not in `s`. A `(k + 1)`-element
subset of `insert a s` either avoids `a` — then it is a `(k + 1)`-element subset of `s` — or
contains `a` — then it is `insert a t` for exactly one `k`-element subset `t` of `s`. The two
kinds do not overlap, so their numbers add up. -/
theorem pascal_subsets {α : Type*} [DecidableEq α] {a : α} {s : Finset α} (ha : a ∉ s)
    (k : ℕ) :
    #(powersetCard (k + 1) (insert a s)) = #(powersetCard (k + 1) s) + #(powersetCard k s) := by
  rw [powersetCard_succ_insert ha, card_union_of_disjoint]
  · -- putting `a` back is one-to-one on the subsets of `s`, since none of them contains `a`
    congr 1
    apply card_image_of_injOn
    intro t ht u hu htu
    have hat : a ∉ t := fun h => ha ((mem_powersetCard.1 ht).1 h)
    have hau : a ∉ u := fun h => ha ((mem_powersetCard.1 hu).1 h)
    have := congrArg (fun v => v.erase a) htu
    simpa [erase_insert hat, erase_insert hau] using this
  · -- no subset of `s` contains `a`, so the two kinds are disjoint
    rw [disjoint_left]
    intro t ht ht'
    obtain ⟨u, -, rfl⟩ := mem_image.1 ht'
    exact ha ((mem_powersetCard.1 ht).1 (mem_insert_self a u))
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/Combinatorics.leanTry it in the Lean web editor

Since counting subsets obeys the same rules that define Nat.choose, induction shows that the two agree:

card_subsets_eq_chooseLean 4Proved here from basic factsFormally verified
/-- **`C(n, k)` counts the `k`-element subsets of an `n`-element set.** Mathlib defines
`Nat.choose` by the rules `C(n, 0) = 1`, `C(0, k + 1) = 0` and Pascal's rule
`C(n + 1, k + 1) = C(n, k) + C(n, k + 1)`. Counting subsets obeys the same three rules
(the last one is `pascal_subsets`), so, by induction on the set, the two agree.
(Mathlib states this as `Finset.card_powersetCard`.) -/
theorem card_subsets_eq_choose {α : Type*} [DecidableEq α] (s : Finset α) (k : ℕ) :
    #(powersetCard k s) = (#s).choose k := by
  induction s using Finset.induction_on generalizing k with
  | empty =>
    cases k with
    | zero => rw [powersetCard_zero, card_singleton, card_empty, Nat.choose_zero_right]
    | succ k =>
      rw [powersetCard_eq_empty.2 (by simp), card_empty, card_empty, Nat.choose_zero_succ]
  | insert a s ha ih =>
    cases k with
    | zero => rw [powersetCard_zero, card_singleton, Nat.choose_zero_right]
    | succ k =>
      rw [pascal_subsets ha, ih, ih, card_insert_of_notMem ha, Nat.choose_succ_succ', add_comm]
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/Combinatorics.leanTry it in the Lean web editor

The factorial formula and symmetry come from Mathlib, and Lean can evaluate the formula exactly:

choose_factorialLean 4Applies a library theoremFormally verified
/-- **The factorial formula.** For `k ≤ n`, `C(n, k) · k! · (n − k)! = n!`, that is
`C(n, k) = n! / (k! (n − k)!)`. This applies Mathlib's `Nat.choose_mul_factorial_mul_factorial`. -/
theorem choose_factorial {n k : ℕ} (hk : k ≤ n) :
    n.choose k * k.factorial * (n - k).factorial = n.factorial :=
  Nat.choose_mul_factorial_mul_factorial hk
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/Combinatorics.leanTry it in the Lean web editor
choose_symmLean 4Applies a library theoremFormally verified
/-- **Symmetry of Pascal's triangle:** `C(n, n − k) = C(n, k)` for `k ≤ n` — choosing the `k`
members of a committee is the same as choosing the `n − k` people left out.
This applies Mathlib's `Nat.choose_symm`. -/
theorem choose_symm {n k : ℕ} (hk : k ≤ n) : n.choose (n - k) = n.choose k :=
  Nat.choose_symm hk
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/Combinatorics.leanTry it in the Lean web editor
five_card_handsLean 4Proved here from basic factsFormally verified
/-- There are `C(52, 5) = 2 598 960` five-card hands from a standard pack. Lean evaluates the
factorial formula exactly. -/
theorem five_card_hands : Nat.choose 52 5 = 2598960 := by
  rw [Nat.choose_eq_factorial_div_factorial (by norm_num)]
  rfl
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/Combinatorics.leanTry it in the Lean web editor

The binomial theorem for (1+x)n(1 + x)^n is proved by induction, as described after Theorem 4. It holds in any commutative semiring — any number system where addition and multiplication obey the usual laws, such as N\N, Z\Z, Q\Q or R\R. Mathlib's general version follows it.

binomial_one_addLean 4Proved here from basic factsFormally verified
/-- **The binomial theorem for `(1 + x)ⁿ`, by induction on `n`.** Multiplying
`(1 + x)ⁿ = Σₖ C(n, k) xᵏ` by `1 + x` gives the sum once as it is and once shifted up by one
power of `x`. Collecting the coefficient of `xᵏ⁺¹` gives `C(n, k + 1) + C(n, k)`, which is
`C(n + 1, k + 1)` by Pascal's rule. -/
theorem binomial_one_add {R : Type*} [CommSemiring R] (x : R) (n : ℕ) :
    (1 + x) ^ n = ∑ k ∈ range (n + 1), (n.choose k : R) * x ^ k := by
  induction n with
  | zero => simp
  | succ n ih =>
    -- the old sum with one extra (zero) term on top
    have top : ∑ k ∈ range (n + 2), (n.choose k : R) * x ^ k =
        ∑ k ∈ range (n + 1), (n.choose k : R) * x ^ k := by
      rw [sum_range_succ, Nat.choose_succ_self, Nat.cast_zero, zero_mul, add_zero]
    -- Pascal's rule, term by term
    have pascal : ∑ k ∈ range (n + 2), ((n + 1).choose k : R) * x ^ k =
        ∑ k ∈ range (n + 1), (n.choose k : R) * x ^ (k + 1) +
          ∑ k ∈ range (n + 2), (n.choose k : R) * x ^ k := by
      rw [sum_range_succ' _ (n + 1), sum_range_succ' (fun k => (n.choose k : R) * x ^ k) (n + 1)]
      simp only [Nat.choose_succ_succ', Nat.cast_add, add_mul, sum_add_distrib,
        Nat.choose_zero_right]
      ring
    rw [pascal, top, pow_succ, ih, mul_add, mul_one, sum_mul]
    simp only [mul_assoc, ← pow_succ]
    ring
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/Combinatorics.leanTry it in the Lean web editor
binomial_theoremLean 4Applies a library theoremFormally verified
/-- **The binomial theorem** `(x + y)ⁿ = Σₖ C(n, k) xᵏ yⁿ⁻ᵏ` in any commutative semiring.
This applies Mathlib's `add_pow` (proved there for any two commuting elements of a semiring). -/
theorem binomial_theorem {R : Type*} [CommSemiring R] (x y : R) (n : ℕ) :
    (x + y) ^ n = ∑ k ∈ range (n + 1), x ^ k * y ^ (n - k) * (n.choose k : R) :=
  add_pow x y n
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/Combinatorics.leanTry it in the Lean web editor
row_sumLean 4Proved here from basic factsFormally verified
/-- **Each row of Pascal's triangle adds up to a power of two:** `Σₖ C(n, k) = 2ⁿ`.
Put `x = 1` in `binomial_one_add`. (Counting proof: both sides count all subsets of an
`n`-element set.) -/
theorem row_sum (n : ℕ) : ∑ k ∈ range (n + 1), n.choose k = 2 ^ n := by
  have h := binomial_one_add (1 : ℕ) n
  simpa [one_add_one_eq_two] using h.symm
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/Combinatorics.leanTry it in the Lean web editor
alternating_row_sumLean 4Proved here from basic factsFormally verified
/-- **Alternating row sums vanish:** `Σₖ (−1)ᵏ C(n + 1, k) = 0`. Put `x = −1` in
`binomial_one_add`: the left side is `(1 − 1)ⁿ⁺¹ = 0`. So a non-empty set has as many subsets
of even size as of odd size. -/
theorem alternating_row_sum (n : ℕ) :
    ∑ k ∈ range (n + 2), ((n + 1).choose k : ℤ) * (-1) ^ k = 0 := by
  have h := binomial_one_add (-1 : ℤ) (n + 1)
  rw [← h]
  simp
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/Combinatorics.leanTry it in the Lean web editor

The pigeonhole principle, proved by counting the objects box by box: if no box held two objects, the number of objects would be at most the number of boxes. Then Mathlib's version, and the remainders example.

pigeonholeLean 4Proved here from basic factsFormally verified
/-- **The pigeonhole principle.** If `f` puts every object of `s` into a box of `t`, and there
are more objects than boxes, then two different objects share a box. Proof by counting: the
number of objects is the sum, over the boxes, of the number of objects in each box. If no box
held two objects, every term would be at most `1`, so there would be at most `#t` objects. -/
theorem pigeonhole {α β : Type*} [DecidableEq β] (s : Finset α) (t : Finset β) (f : α → β)
    (hf : ∀ a ∈ s, f a ∈ t) (hst : #t < #s) : ∃ x ∈ s, ∃ y ∈ s, x ≠ y ∧ f x = f y := by
  by_contra! h
  -- if no two objects share a box, every box holds at most one object
  have hbox : ∀ b ∈ t, #{a ∈ s | f a = b} ≤ 1 := by
    intro b _
    rw [card_le_one]
    intro x hx y hy
    rw [mem_filter] at hx hy
    by_contra hxy
    exact h x hx.1 y hy.1 hxy (hx.2.trans hy.2.symm)
  have : #s ≤ #t :=
    calc #s = ∑ b ∈ t, #{a ∈ s | f a = b} := card_eq_sum_card_fiberwise (fun a ha => hf a ha)
      _ ≤ ∑ b ∈ t, 1 := sum_le_sum hbox
      _ = #t := by simp
  omega
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/Combinatorics.leanTry it in the Lean web editor
pigeonhole_libraryLean 4Applies a library theoremFormally verified
/-- The same principle from Mathlib: `Finset.exists_ne_map_eq_of_card_lt_of_maps_to`. -/
theorem pigeonhole_library {α β : Type*} (s : Finset α) (t : Finset β) (f : α → β)
    (hf : ∀ a ∈ s, f a ∈ t) (hst : #t < #s) : ∃ x ∈ s, ∃ y ∈ s, x ≠ y ∧ f x = f y :=
  exists_ne_map_eq_of_card_lt_of_maps_to hst (fun a ha => hf a ha)
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/Combinatorics.leanTry it in the Lean web editor
same_remainderLean 4Proved here from basic factsFormally verified
/-- **Among any `n + 1` integers, two differ by a multiple of `n`.** The boxes are the `n`
possible remainders `0, 1, …, n − 1` on division by `n`; there are `n + 1` integers, so two of
them have the same remainder, and their difference is divisible by `n`. Nothing tells us
*which* two — the pigeonhole principle only proves that they exist. -/
theorem same_remainder (n : ℕ) (hn : 0 < n) (a : Fin (n + 1) → ℤ) :
    ∃ i j, i ≠ j ∧ (n : ℤ) ∣ a i - a j := by
  have hn' : (0 : ℤ) < n := by exact_mod_cast hn
  obtain ⟨i, -, j, -, hij, h⟩ :=
    pigeonhole (univ : Finset (Fin (n + 1))) (Ico (0 : ℤ) n) (fun i => a i % n)
      (fun i _ => mem_Ico.2 ⟨Int.emod_nonneg _ hn'.ne', Int.emod_lt_of_pos _ hn'⟩)
      (by simp)
  exact ⟨i, j, hij, Int.ModEq.dvd h.symm⟩
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/Combinatorics.leanTry it in the Lean web editor

Inclusion–exclusion. Subtraction of natural numbers is awkward (in Lean, 3−5=03 - 5 = 0 in N\N), so the formulas are written with every term on the side where it is added:

incl_excl_twoLean 4Applies a library theoremFormally verified
/-- **Inclusion–exclusion for two sets:** `|A ∪ B| + |A ∩ B| = |A| + |B|` (written without
subtraction, which is awkward in `ℕ`). This applies Mathlib's
`Finset.card_union_add_card_inter`. -/
theorem incl_excl_two {α : Type*} [DecidableEq α] (A B : Finset α) :
    #(A ∪ B) + #(A ∩ B) = #A + #B :=
  card_union_add_card_inter A B
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/Combinatorics.leanTry it in the Lean web editor
incl_excl_threeLean 4Proved here from basic factsFormally verified
/-- **Inclusion–exclusion for three sets:**
`|A ∪ B ∪ C| = |A| + |B| + |C| − |A ∩ B| − |A ∩ C| − |B ∩ C| + |A ∩ B ∩ C|`,
written with every term on the side where it is added. The proof is the lesson's: apply the
two-set rule to `A ∪ B` and `C`, then to `A` and `B`, then to `A ∩ C` and `B ∩ C`, using
`(A ∪ B) ∩ C = (A ∩ C) ∪ (B ∩ C)`. -/
theorem incl_excl_three {α : Type*} [DecidableEq α] (A B C : Finset α) :
    #(A ∪ B ∪ C) + #(A ∩ B) + #(A ∩ C) + #(B ∩ C) = #A + #B + #C + #(A ∩ B ∩ C) := by
  have h1 := card_union_add_card_inter (A ∪ B) C
  have h2 := card_union_add_card_inter A B
  have h3 := card_union_add_card_inter (A ∩ C) (B ∩ C)
  have e1 : (A ∪ B) ∩ C = A ∩ C ∪ B ∩ C := union_inter_distrib_right A B C
  have e2 : A ∩ C ∩ (B ∩ C) = A ∩ B ∩ C := by
    ext x
    simp only [mem_inter]
    tauto
  rw [e1] at h1
  rw [e2] at h3
  omega
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/Combinatorics.leanTry it in the Lean web editor
divisible_by_2_3_or_5Lean 4Proved here from basic factsFormally verified
/-- Of the numbers `1, 2, …, 100`, exactly `74` are divisible by `2`, `3` or `5`, as
inclusion–exclusion predicts: `50 + 33 + 20 − 16 − 10 − 6 + 3 = 74`. Lean checks all hundred. -/
theorem divisible_by_2_3_or_5 :
    #{n ∈ Icc 1 100 | 2 ∣ n ∨ 3 ∣ n ∨ 5 ∣ n} = 74 := by
  decide
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/Combinatorics.leanTry it in the Lean web editor

What is not formalised here: the general inclusion–exclusion formula (Mathlib has it, as Finset.inclusion_exclusion_card_biUnion, but its statement takes some unpacking), the derangement formula, and the geometric pigeonhole examples.

ComputationC

Counting by computer

Pascal's triangle three ways, and the binomial theoremPythonExhaustive finite checkExact computationSymbolic computationComputationally tested
"""Pascal's triangle three ways, and the binomial theorem checked symbolically.

The number of k-element subsets of an n-element set is computed in three
independent ways - by listing every subset (itertools.combinations), by
Pascal's rule, and by the factorial formula - and the three are compared for
every n up to 12 (listing) or 40 (rule versus formula). The row identities
(symmetry, row sums 2^n, alternating sums 0) are checked on the same range,
and SymPy expands (x + y)^n to confirm that its coefficients are the rows of
the triangle for n up to 12. All of this is exhaustive over a finite range:
evidence for the identities, which the lesson proves for every n.
"""

import itertools
import math

import sympy

def pascal_rows(n_max):
    """Rows 0..n_max of Pascal's triangle, built only from Pascal's rule."""
    rows = [[1]]
    for _ in range(n_max):
        prev = rows[-1]
        rows.append([1] + [prev[k - 1] + prev[k] for k in range(1, len(prev))]
                    + [1])
    return rows

def count_subsets(n, k):
    """Number of k-element subsets of {0, ..., n-1}, by listing them all."""
    return sum(1 for _ in itertools.combinations(range(n), k))

def factorial_formula(n, k):
    """n! / (k! (n - k)!), computed with exact integers."""
    if not 0 <= k <= n:
        return 0
    return math.factorial(n) // (math.factorial(k) * math.factorial(n - k))

def binomial_coefficients(n):
    """Coefficients of x^k y^(n-k), k = 0..n, in SymPy's expansion of (x+y)^n."""
    x, y = sympy.symbols("x y")
    poly = sympy.Poly(sympy.expand((x + y) ** n), x, y)
    return [int(poly.coeff_monomial(x ** k * y ** (n - k)))
            for k in range(n + 1)]

def row_identities_hold(row):
    """Symmetry, row sum 2^n and alternating sum 0 (for n >= 1) for one row."""
    n = len(row) - 1
    alternating = sum((-1) ** k * c for k, c in enumerate(row))
    return (row == row[::-1] and sum(row) == 2 ** n
            and (n == 0 or alternating == 0))

def main():
    rows = pascal_rows(40)
    print("Rows 0-8 of Pascal's triangle (built from Pascal's rule):")
    for n in range(9):
        print(" " * (2 * (8 - n)) + "".join(f"{c:4d}" for c in rows[n]))
    listed = all(count_subsets(n, k) == rows[n][k]
                 for n in range(13) for k in range(n + 1))
    print(f"Listing subsets agrees with the rule for all n <= 12: {listed}")
    formula = all(factorial_formula(n, k) == rows[n][k]
                  for n in range(41) for k in range(n + 1))
    print(f"Factorial formula agrees with the rule for all n <= 40: {formula}")
    rows_ok = all(row_identities_hold(row) for row in rows)
    print(f"Symmetry, sums 2^n, alternating sums 0 (n <= 40): {rows_ok}")
    print(f"Row 40 has {sum(rows[40])} subsets in all = 2^40.")
    expansion = sympy.expand((sympy.Symbol("x") + sympy.Symbol("y")) ** 5)
    print("SymPy expands (x + y)^5 as")
    print(f"  {expansion}")
    sym = all(binomial_coefficients(n) == rows[n] for n in range(13))
    print(f"Coefficients of (x + y)^n = row n for all n <= 12: {sym}")
    print()
    print("Epistemic status: exhaustive checks over a finite range (listing")
    print("subsets for n <= 12, exact integer arithmetic for n <= 40) and a")
    print("symbolic expansion trusted as far as SymPy is. They support, but")
    print("cannot prove, the identities for all n; the lesson's counting and")
    print("induction proofs (checked in Lean) do that.")

if __name__ == "__main__":
    main()
Runs entirely in your browser, in an isolated worker. Nothing is sent to a server.
Inclusion-exclusion, derangements and birthdaysPythonExact computationExhaustive finite checkComputationally tested
"""Inclusion-exclusion and the pigeonhole principle, counted exactly.

Three checks. (1) How many of 1..N are divisible by 2, 3 or 5? Counting
every number agrees with the inclusion-exclusion formula. (2) Derangements:
the number of ways to hand back n hats so that nobody gets their own is found
by listing all n! arrangements (n <= 8) and agrees with the general
inclusion-exclusion formula n! * sum (-1)^k / k!; the fraction approaches
1/e. (3) Birthdays: the exact probability that k people (365 equally likely
days) share a birthday passes 1/2 at k = 23, but only the pigeonhole
principle makes it certain, at k = 366.
"""

import itertools
import math
from fractions import Fraction

def divisible_count_direct(n, divisors):
    """How many of 1..n are divisible by at least one of the divisors."""
    return sum(1 for m in range(1, n + 1) if any(m % d == 0 for d in divisors))

def divisible_count_ie(n, divisors):
    """The same count by inclusion-exclusion over all non-empty subsets."""
    total = 0
    for r in range(1, len(divisors) + 1):
        for subset in itertools.combinations(divisors, r):
            lcm = math.lcm(*subset)
            total += (-1) ** (r + 1) * (n // lcm)
    return total

def derangements_brute(n):
    """Arrangements of 0..n-1 with no element in its own place, by listing."""
    return sum(1 for p in itertools.permutations(range(n))
               if all(p[i] != i for i in range(n)))

def derangements_ie(n):
    """n! * sum_{k=0}^{n} (-1)^k / k!, the inclusion-exclusion count."""
    return sum((-1) ** k * math.factorial(n) // math.factorial(k)
               for k in range(n + 1))

def shared_birthday(k, days=365):
    """Exact probability that some two of k people share a birthday."""
    if k > days:
        return Fraction(1)
    none = Fraction(1)
    for i in range(k):
        none *= Fraction(days - i, days)
    return 1 - none

def main():
    print("1. Numbers in 1..N divisible by 2, 3 or 5")
    for n in (100, 1000, 30000):
        direct = divisible_count_direct(n, (2, 3, 5))
        print(f"   N = {n:5d}: counted {direct:5d}, inclusion-exclusion "
              f"{divisible_count_ie(n, (2, 3, 5)):5d}")
    print()
    print("2. Derangements (nobody gets their own hat)")
    print("    n   listed   formula   fraction of n!   1/e = 0.367879")
    for n in range(1, 9):
        listed = derangements_brute(n)
        frac = listed / math.factorial(n)
        print(f"   {n:2d}   {listed:6d}   {derangements_ie(n):7d}   "
              f"{frac:14.6f}")
    print()
    print("3. Shared birthdays among k people (365 equally likely days)")
    print("      k   P(shared)   P(no two share)")
    for k in (10, 22, 23, 50, 70, 365, 366):
        p = shared_birthday(k)
        none = "exactly 0" if p == 1 else f"{float(1 - p):.3e}"
        print(f"   {k:4d}   {float(p):9.6f}   {none}")
    print()
    print("Epistemic status: exact integer and rational arithmetic. Parts 1")
    print("and 2 compare a direct count with a formula over a finite range")
    print("(evidence; the lesson proves the formulas). Part 3 is an exact")
    print("model calculation assuming 365 equally likely, independent days.")

if __name__ == "__main__":
    main()
Runs entirely in your browser, in an isolated worker. Nothing is sent to a server.

Look at the last table. With 2323 people a shared birthday is already more likely than not (assuming 365365 equally likely birthdays) — but no number of people below 366366 makes it certain: even with 365365 people the probability that all birthdays differ is tiny but not zero. Only the pigeonhole principle, at 366366 people, turns "very likely" into "guaranteed". Probability and pigeonhole answer different questions.

Explore

Explore: Pascal's triangle in a Galton board

Binomial coefficients and birthdays

Balls bounce left or right at each row of pegs. The bins fill up in a binomial shape, close to a normal curve.

012345678910number of bounces to the right
  • balls in each bin
  • exact binomial expectation
  • normal approximation
  • path of the latest ball

Average bin

Simulated4.98

Exactn/2 = 5

Balls in bin 5

Simulated249

Exact≈ 246.1

Simulation of 1,000 balls through 10 rows: the average bin was 4.98. The exact average is half the number of rows.

Evidence, not proofThis is a simulation of 1,000 balls (run 1) using a seeded random number generator. It is evidence, not proof: the exact values come from mathematics, and a new run gives slightly different numbers.

Bin j collects the balls that bounced right j times. C(n, j) of the 2ⁿ equally likely paths lead there, so the exact chance is C(n, j)/2ⁿ. With many rows this binomial shape is close to a normal curve (the central limit theorem).

On the Galton board, each ball bounces left or right at each of 1010 rows. A ball lands in bin jj when exactly jj of its 1010 bounces go right, and there are (10j)\binom{10}{j} such paths — row 1010 of Pascal's triangle — out of 210=10242^{10} = 1024 equally likely paths. Compare the bars with the exact shape, then increase the number of balls. On the birthday tab, change the group size: find where the probability first passes one half, and notice that it creeps towards 11 without reaching it.

Exercises

Exercises

1. Combinatorics

Warm-upHuman

A youth council in Kigali has 99 members. In how many ways can a working group of 44 members be chosen? (All members of the group have the same role.)

2. Combinatorics

Warm-upHuman

Find all whole numbers kk with (10k)=120\binom{10}{k} = 120. List them separated by commas.

Write elements separated by commas. Order and repeats don’t matter — just like in a set!

3. Combinatorics

CoreHuman

How many five-card hands from a standard pack of 5252 cards contain at least one ace? (There are (525)=2 598 960\binom{52}{5} = 2\,598\,960 hands in all, and (485)=1 712 304\binom{48}{5} = 1\,712\,304.)

4. Combinatorics

CoreHuman

What is the coefficient of x3x^3 in the expansion of (2x+1)5(2x + 1)^5?

5. Combinatorics

CoreHuman

In the proof of Pascal's rule (nk)=(n−1k−1)+(n−1k)\binom{n}{k} = \binom{n-1}{k-1} + \binom{n-1}{k}, the kk-person committees chosen from nn people are split by whether they contain Amina. Why are there exactly (n−1k−1)\binom{n-1}{k-1} committees containing Amina?

Choose one

6. Combinatorics

CoreHuman

In a class of 4040 students in Accra, 2222 play football, 1515 play basketball and 88 play both. How many students play neither sport?

7. Combinatorics

StretchHuman

What is the smallest number mm such that any mm different whole numbers chosen from 1,2,…,1001, 2, \dots, 100 must include two whose difference is divisible by 77?

8. Combinatorics

StretchFormal

Here s is a finite set of objects, t a finite set of boxes and f assigns a box to each object. Which Lean statement correctly formalises the pigeonhole principle?

Choose one

9. Combinatorics

StretchComputational

Write derangements(n) returning the number of ways to arrange nn hats so that nobody gets their own hat, using the inclusion–exclusion formula Dn=∑k=0n(−1)kn!k!D_n = \sum_{k=0}^{n} (-1)^k \dfrac{n!}{k!}. Use exact integer arithmetic (math.factorial and //). Then check: does Dn/n!D_n / n! approach 1/e≈0.36791/e \approx 0.3679?

Runs entirely in your browser, in an isolated worker. Nothing is sent to a server.
Common misconceptionsH

Common misconceptions

Misconception

Using permutations when order does not matter. Choosing a committee of 33 from 77 is (73)=35\binom{7}{3} = 35, not 7×6×5=2107 \times 6 \times 5 = 210. The ordered count lists each committee 3!=63! = 6 times. Ask: "if I swap two of my choices, do I get a different outcome?" If not, order does not matter.

Misconception

"A pigeonhole argument must say which box has two objects." It need not, and usually cannot. "Two of these 1313 people share a birth month" is proved without knowing any birthdays at all.

Misconception

"(x+y)n=xn+yn(x + y)^n = x^n + y^n." Already (x+y)2=x2+2xy+y2(x + y)^2 = x^2 + 2xy + y^2. The binomial theorem shows exactly which cross terms appear and how often.

Misconception

Counting "at least one" by fixing one. Choosing "the" ace first and then the rest counts hands with several aces several times. Count the complement ("no aces") instead, or use inclusion–exclusion.

Misconception

Stopping inclusion–exclusion too early. For three sets, after subtracting the pairwise intersections the elements of A∩B∩CA \cap B \cap C have been added three times and subtracted three times — so they must be added back once.

ViewpointsH

Other ways of seeing

Algebra— Counting with polynomials

The binomial theorem says that the polynomial (1+x)n(1 + x)^n stores the numbers (nk)\binom{n}{k} as its coefficients. Identities between counts become identities between polynomials: comparing the coefficient of xkx^k on both sides of (1+x)m+n=(1+x)m(1+x)n(1 + x)^{m+n} = (1 + x)^m (1 + x)^n gives Vandermonde's identity (m+nk)=∑j(mj)(nk−j)\binom{m+n}{k} = \sum_j \binom{m}{j}\binom{n}{k-j} — which also has a counting proof (choose kk people from mm women and nn men). Turning counting problems into algebra in this way is the method of generating functions, the subject of recurrences and generating functions and enumerative combinatorics.

Probability— Counting is probability in disguise

If a fair coin is tossed nn times, the 2n2^n sequences are equally likely, and (nk)\binom{n}{k} of them have exactly kk heads. So P(k heads)=(nk)/2nP(k \text{ heads}) = \binom{n}{k} / 2^n — the binomial distribution, the shape of the Galton board. Many probability questions are two counting questions, divided; see conditional probability and independence.

Number theory— Primes in Pascal's triangle

If pp is prime and 0<k<p0 < k < p, then pp divides (pk)=p!k! (p−k)!\binom{p}{k} = \dfrac{p!}{k!\,(p-k)!}: the prime pp divides the numerator but not the denominator. (Look at row 77: 1,7,21,35,35,21,7,11, 7, 21, 35, 35, 21, 7, 1.) So (a+b)p(a + b)^p and ap+bpa^p + b^p leave the same remainder on division by pp, and an induction on aa then proves Fermat's little theorem: pp divides ap−aa^p - a for every whole number aa. Colouring the odd entries of Pascal's triangle reveals a pattern like the Sierpiński triangle, explained by Lucas's theorem on binomial coefficients modulo a prime; see congruences.

Set-theoretic connectionH

Set-theoretic connection

Combinatorics is the theory of the sizes of finite sets. The multiplication principle is ∣A×B∣=∣A∣⋅∣B∣|A \times B| = |A| \cdot |B|; the binomial coefficient counts the subsets of size kk inside the power set P(X)\mathcal{P}(X), which has 2∣X∣2^{|X|} elements; a "counting in two ways" proof is the statement that two finite sets in one-to-one correspondence have the same size; and inclusion–exclusion computes the size of a union from the sizes of intersections. The pigeonhole principle says exactly that there is no one-to-one function from a finite set to a smaller one — a fact that fails for infinite sets, as countability shows.

History & global context

History and global context

  • India. Piṅgala's Chandaḥśāstra (roughly the 3rd–2nd century BCE) counts the patterns of short and long syllables in Sanskrit verse; its 10th-century commentator Halāyudha describes the meru-prastāra, the "staircase of Mount Meru" — the triangle we call Pascal's. Varāhamihira (6th century) counted the perfumes that can be blended by choosing 44 of 1616 ingredients ((164)=1820\binom{16}{4} = 1820), and Mahāvīra's Gaṇitasārasaṅgraha (around 850) gives the general rule for (nk)\binom{n}{k}.
  • Persia and North Africa. Al-Karajī (around 1000) used the triangle to expand powers of a binomial; his work is known through al-Samawʾal (12th century). In Iran the triangle is often named after Omar Khayyam. In Marrakesh, Ibn Munʿim (died 1228) used a table of the same numbers to count the possible words of a language.
  • China. Jia Xian (11th century) used the triangle to extract roots; it is preserved in Yang Hui's book of 1261 — in China it is called Yang Hui's triangle — and drawn in Zhu Shijie's Jade Mirror of the Four Unknowns (1303).
  • Europe. Levi ben Gershon's Maaseh Hoshev (1321) gave formulas for arrangements and selections with careful proofs. Blaise Pascal's Traité du triangle arithmétique (written 1654, published 1665) proved many of its properties systematically and applied them to probability; Isaac Newton extended the binomial theorem to fractional exponents (1665).
  • Pigeons and hats. The pigeonhole principle is named after P. G. L. Dirichlet, who used it in 1834 (as the Schubfachprinzip, "drawer principle"); it appears earlier, in a 1622 book by the French Jesuit Jean Leurechon. The hat-check problem goes back to Pierre Rémond de Montmort's problème des rencontres (1708), and Abraham de Moivre used inclusion–exclusion in The Doctrine of Chances (1718).
Further reading

Further reading

  • Arthur Engel, Problem-Solving Strategies (1998) — chapters on the pigeonhole principle and on enumerative combinatorics, with hundreds of competition problems.
  • Arthur T. Benjamin and Jennifer J. Quinn, Proofs That Really Count (2003) — identities proved by counting in two ways.
  • Richard A. Brualdi, Introductory Combinatorics (5th edition, 2010).
  • Ronald L. Graham, Donald E. Knuth and Oren Patashnik, Concrete Mathematics (2nd edition, 1994), chapter 5 on binomial coefficients.
  • A. W. F. Edwards, Pascal's Arithmetical Triangle (1987), for the history of the triangle.