Counting fundamentals
Counting without listing: the addition and multiplication principles, permutations P(n, k), combinations C(n, k), the binomial theorem, the pigeonhole principle and a first look at inclusion-exclusion. These give the sizes of search spaces and the number of states a brute force would visit.
Learning goals
- Choose between addition and multiplication
- Compute nPr and nCr and know when order matters
- Apply the pigeonhole principle and inclusion-exclusion
Prerequisites
Addition/multiplication principles
Addition: if a task can be done in one of two mutually exclusive ways with a and b options, there are a + b outcomes. Multiplication: if it takes a sequence of independent choices with a then b options, there are a × b outcomes.
A 4-character lowercase code has 26⁴ = 456,976 possibilities. Brute force over a binary string of length n takes 2ⁿ steps.
| Situation | Rule | Count |
|---|---|---|
| Choose a shirt (5) or a jacket (3) | add | 8 |
| Choose a shirt (5) and trousers (4) | multiply | 20 |
| Binary string of length 10 | multiply | 2¹⁰ = 1,024 |
| PIN with 4 digits | multiply | 10⁴ = 10,000 |
nPr
P(n, k) = n! / (n - k)! = n · (n - 1) · … · (n - k + 1) counts ordered selections of k items from n. Order matters: “first, second, third place” among 10 runners is P(10, 3) = 720.
Set n and k below to see the formula and the list of arrangements.
1static long perm(int n, int k) { long r = 1; for (int i = 0; i < k; i++) r *= (n - i); return r; }2long podium = perm(10, 3); // 720
Permutations nPr and combinations nCr
Interactive · edit the inputitems
current choice
found so far (0 of 12)
Choose 2 of 4 items where order matters: n × (n-1) × … = 4! / 2! = 12.
1static void pick(int[] items, int r, boolean ordered, int start,2List<Integer> current, boolean[] used, List<List<Integer>> out) {3if (current.size() == r) { out.add(new ArrayList<>(current)); return; }4for (int i = ordered ? 0 : start; i < items.length; i++) {5if (used[i]) continue; // each item at most once6used[i] = true;7current.add(items[i]);8pick(items, r, ordered, i + 1, current, used, out);9current.remove(current.size() - 1); // backtrack10used[i] = false;11}12}
Live state
n
4
r
2
expected
12
Execution trace (dry run table)Show 30 stepsHide
| Step | Line | State | What happens |
|---|---|---|---|
| 1 | L1 | n=4 r=2 expected=12 | Choose 2 of 4 items where order matters: n × (n-1) × … = 4! / 2! = 12. |
| 2 | L7 | picked=1 size=1 r=2 | Pick 1: choice 1 of 2. There were 4 options for the first slot, 3 for the second, and so on (multiplication principle). |
| 3 | L7 | picked=2 size=2 r=2 | Pick 2: choice 2 of 2. |
| 4 | L3 | found=1 expected=12 | Complete: 1, 2. That is arrangement #1. |
| 5 | L7 | picked=3 size=2 r=2 | Pick 3: choice 2 of 2. |
| 6 | L3 | found=2 expected=12 | Complete: 1, 3. That is arrangement #2. |
| 7 | L7 | picked=4 size=2 r=2 | Pick 4: choice 2 of 2. |
| 8 | L3 | found=3 expected=12 | Complete: 1, 4. That is arrangement #3. |
| 9 | L7 | picked=2 size=1 r=2 | Pick 2: choice 1 of 2. There were 4 options for the first slot, 3 for the second, and so on (multiplication principle). |
| 10 | L7 | picked=1 size=2 r=2 | Pick 1: choice 2 of 2. |
| 11 | L3 | found=4 expected=12 | Complete: 2, 1. That is arrangement #4. |
| 12 | L7 | picked=3 size=2 r=2 | Pick 3: choice 2 of 2. |
| 13 | L3 | found=5 expected=12 | Complete: 2, 3. That is arrangement #5. |
| 14 | L7 | picked=4 size=2 r=2 | Pick 4: choice 2 of 2. |
| 15 | L3 | found=6 expected=12 | Complete: 2, 4. That is arrangement #6. |
| 16 | L7 | picked=3 size=1 r=2 | Pick 3: choice 1 of 2. There were 4 options for the first slot, 3 for the second, and so on (multiplication principle). |
| 17 | L7 | picked=1 size=2 r=2 | Pick 1: choice 2 of 2. |
| 18 | L3 | found=7 expected=12 | Complete: 3, 1. That is arrangement #7. |
| 19 | L7 | picked=2 size=2 r=2 | Pick 2: choice 2 of 2. |
| 20 | L3 | found=8 expected=12 | Complete: 3, 2. That is arrangement #8. |
| 21 | L7 | picked=4 size=2 r=2 | Pick 4: choice 2 of 2. |
| 22 | L3 | found=9 expected=12 | Complete: 3, 4. That is arrangement #9. |
| 23 | L7 | picked=4 size=1 r=2 | Pick 4: choice 1 of 2. There were 4 options for the first slot, 3 for the second, and so on (multiplication principle). |
| 24 | L7 | picked=1 size=2 r=2 | Pick 1: choice 2 of 2. |
| 25 | L3 | found=10 expected=12 | Complete: 4, 1. That is arrangement #10. |
| 26 | L7 | picked=2 size=2 r=2 | Pick 2: choice 2 of 2. |
| 27 | L3 | found=11 expected=12 | Complete: 4, 2. That is arrangement #11. |
| 28 | L7 | picked=3 size=2 r=2 | Pick 3: choice 2 of 2. |
| 29 | L3 | found=12 expected=12 | Complete: 4, 3. That is arrangement #12. |
| 30 | L12 | found=12 formula=12 return=12 | 12 arrangements listed, matching 4! / 2! = 12. The formula gives the count without listing them: that is the point of counting principles. |
nCr
C(n, k) = n! / (k! (n - k)!) counts unordered selections. It equals P(n, k) / k!, because each group of k items has k! orderings. C(n, k) = C(n, n - k), and Pascal's rule C(n, k) = C(n - 1, k - 1) + C(n - 1, k) builds all values additively, avoiding large factorials.
C(5, 2) = 10 handshakes among 5 people. Switch the animation to combinations to see the groups.
1static long comb(int n, int k) {2k = Math.min(k, n - k);3long r = 1;4for (int i = 1; i <= k; i++) r = r * (n - k + i) / i; // exact at every step5return r;6}7long c = comb(52, 5); // 2598960 poker hands
Permutations nPr and combinations nCr
Interactive · edit the inputitems
current choice
found so far (0 of 12)
Choose 2 of 4 items where order matters: n × (n-1) × … = 4! / 2! = 12.
1static void pick(int[] items, int r, boolean ordered, int start,2List<Integer> current, boolean[] used, List<List<Integer>> out) {3if (current.size() == r) { out.add(new ArrayList<>(current)); return; }4for (int i = ordered ? 0 : start; i < items.length; i++) {5if (used[i]) continue; // each item at most once6used[i] = true;7current.add(items[i]);8pick(items, r, ordered, i + 1, current, used, out);9current.remove(current.size() - 1); // backtrack10used[i] = false;11}12}
Live state
n
4
r
2
expected
12
Execution trace (dry run table)Show 30 stepsHide
| Step | Line | State | What happens |
|---|---|---|---|
| 1 | L1 | n=4 r=2 expected=12 | Choose 2 of 4 items where order matters: n × (n-1) × … = 4! / 2! = 12. |
| 2 | L7 | picked=1 size=1 r=2 | Pick 1: choice 1 of 2. There were 4 options for the first slot, 3 for the second, and so on (multiplication principle). |
| 3 | L7 | picked=2 size=2 r=2 | Pick 2: choice 2 of 2. |
| 4 | L3 | found=1 expected=12 | Complete: 1, 2. That is arrangement #1. |
| 5 | L7 | picked=3 size=2 r=2 | Pick 3: choice 2 of 2. |
| 6 | L3 | found=2 expected=12 | Complete: 1, 3. That is arrangement #2. |
| 7 | L7 | picked=4 size=2 r=2 | Pick 4: choice 2 of 2. |
| 8 | L3 | found=3 expected=12 | Complete: 1, 4. That is arrangement #3. |
| 9 | L7 | picked=2 size=1 r=2 | Pick 2: choice 1 of 2. There were 4 options for the first slot, 3 for the second, and so on (multiplication principle). |
| 10 | L7 | picked=1 size=2 r=2 | Pick 1: choice 2 of 2. |
| 11 | L3 | found=4 expected=12 | Complete: 2, 1. That is arrangement #4. |
| 12 | L7 | picked=3 size=2 r=2 | Pick 3: choice 2 of 2. |
| 13 | L3 | found=5 expected=12 | Complete: 2, 3. That is arrangement #5. |
| 14 | L7 | picked=4 size=2 r=2 | Pick 4: choice 2 of 2. |
| 15 | L3 | found=6 expected=12 | Complete: 2, 4. That is arrangement #6. |
| 16 | L7 | picked=3 size=1 r=2 | Pick 3: choice 1 of 2. There were 4 options for the first slot, 3 for the second, and so on (multiplication principle). |
| 17 | L7 | picked=1 size=2 r=2 | Pick 1: choice 2 of 2. |
| 18 | L3 | found=7 expected=12 | Complete: 3, 1. That is arrangement #7. |
| 19 | L7 | picked=2 size=2 r=2 | Pick 2: choice 2 of 2. |
| 20 | L3 | found=8 expected=12 | Complete: 3, 2. That is arrangement #8. |
| 21 | L7 | picked=4 size=2 r=2 | Pick 4: choice 2 of 2. |
| 22 | L3 | found=9 expected=12 | Complete: 3, 4. That is arrangement #9. |
| 23 | L7 | picked=4 size=1 r=2 | Pick 4: choice 1 of 2. There were 4 options for the first slot, 3 for the second, and so on (multiplication principle). |
| 24 | L7 | picked=1 size=2 r=2 | Pick 1: choice 2 of 2. |
| 25 | L3 | found=10 expected=12 | Complete: 4, 1. That is arrangement #10. |
| 26 | L7 | picked=2 size=2 r=2 | Pick 2: choice 2 of 2. |
| 27 | L3 | found=11 expected=12 | Complete: 4, 2. That is arrangement #11. |
| 28 | L7 | picked=3 size=2 r=2 | Pick 3: choice 2 of 2. |
| 29 | L3 | found=12 expected=12 | Complete: 4, 3. That is arrangement #12. |
| 30 | L12 | found=12 formula=12 return=12 | 12 arrangements listed, matching 4! / 2! = 12. The formula gives the count without listing them: that is the point of counting principles. |
Binomial theorem
(x + y)ⁿ = Σ C(n, k) xⁿ⁻ᵏ yᵏ. The coefficients form row n of Pascal's triangle. Setting x = y = 1 gives Σ C(n, k) = 2ⁿ, the number of subsets of an n-element set.
For example (x + y)⁴ = x⁴ + 4x³y + 6x²y² + 4xy³ + y⁴ and the coefficients sum to 16 = 2⁴.
| n | C(n, 0) … C(n, n) | Sum |
|---|---|---|
| 0 | 1 | 1 |
| 1 | 1 1 | 2 |
| 2 | 1 2 1 | 4 |
| 3 | 1 3 3 1 | 8 |
| 4 | 1 4 6 4 1 | 16 |
| 5 | 1 5 10 10 5 1 | 32 |
Pigeonhole principle
If more than n items go into n boxes, some box holds at least two items. In general some box holds at least ⌈items / n⌉. Consequences: any hash function into m buckets collides once there are m + 1 keys; any set of n + 1 integers contains two whose difference is divisible by n.
It proves existence without finding the item, so it is often used to show that a collision or repeat must happen.
Inclusion-exclusion introduction
To count the union of overlapping sets, add the sizes and subtract the overlaps: |A ∪ B| = |A| + |B| - |A ∩ B|, and for three sets |A ∪ B ∪ C| = |A| + |B| + |C| - |A ∩ B| - |A ∩ C| - |B ∩ C| + |A ∩ B ∩ C|.
Example: how many numbers from 1 to 999 are multiples of 3 or 5? 333 + 199 - 66 = 466, where 66 counts the multiples of 15.
1int n = 999;2int count = n / 3 + n / 5 - n / 15; // 333 + 199 - 66 = 4663int brute = 0;4for (int i = 1; i <= n; i++) if (i % 3 == 0 || i % 5 == 0) brute++; // 466
Practice ladder
Now try it yourself
Easy
- How many 3-letter codes from A–Z allow repeats? From distinct letters?
- Compute C(6, 2)
Medium
- How many ways to pick a team of 3 from 8 people and then a captain from the team?
- Count multiples of 2, 3 or 5 up to 100 with inclusion-exclusion
Advanced
- Show that among any 5 integers two have the same remainder modulo 4
Key takeaways
- Multiply for sequential choices, add for alternatives.
- Order matters: P(n, k); order does not: C(n, k) = P(n, k) / k!.
- Pigeonhole forces collisions; inclusion-exclusion corrects double counting.