How do you count the ways to place n distinct records into k named buckets with no bucket left empty?
answer
- all placements are k to the n
- forbidden placements miss at least one bucket
- avoiding j buckets leaves (k-j) choices each
- sum over j of (-1)^j C(k,j) (k-j)^n
- only k+1 terms, not 2^k
basics
~20 sTake all k^n placements and remove those that miss at least one bucket by an alternating sum: sum over j of (-1)^j C(k,j) (k-j)^n. For 5 records into 3 buckets that is 243 - 96 + 3 = 150.
solid answer
~50 sEvery placement of `n` distinct records into `k` named buckets is one of `k^n` functions. The forbidden ones are those that leave some bucket empty, so define `Ai` as the placements that miss bucket `i`; there are `(k-1)^n` of those, and `C(k,j)(k-j)^n` placements that miss a chosen set of `j` buckets. The signed sum gives `onto = sum over j from 0 to k of (-1)^j C(k,j) (k-j)^n`. For `n = 5`, `k = 3`: `243 - 3 x 32 + 3 x 1 = 150`. The alternation matters because a placement missing two buckets sits in two of the single-empty terms and would otherwise be removed twice. The sum has `k+1` terms - it grows with the number of buckets, not with the record count - so it stays cheap even for large `n`.
go deeper
Recall that placements of n distinct records into k buckets number k^n, and that requiring every bucket to be used removes a large share of them.
Explain the complement construction: count placements avoiding a chosen set of buckets, then alternate signs so a placement missing two buckets is removed exactly once.
Show the checks - the k! times unlabelled-partition identity, the zero when n is below k - and note that symmetry collapses the sum to k+1 terms.
Use the coverage ratio to argue design: if a meaningful share of random routings starve a bucket, the routing stage needs deterministic assignment rather than hashing and hoping.
## What is being counted A routing stage sends each of `n` distinguishable records to one of `k` named buckets - partitions of a work queue, output files, worker slots. The placements are all `k^n` of them, since each record independently picks a bucket. The constraint of interest is **coverage**: every bucket must receive at least one record, because an empty bucket means an idle consumer or a missing output. Counting the placements that achieve full coverage is counting **surjections** - onto functions - from records to buckets. ## Why the direct count is hard and the complement is easy There is no simple product formula for onto placements, because the constraint couples the records: whether the last record may go anywhere depends on what the earlier ones did. The complement is far more tractable. Fix a set of `j` buckets and ask for the placements that use **none** of them: every record has `k - j` remaining choices, so there are `(k-j)^n` such placements, and `C(k,j)` ways to choose which `j` buckets are avoided. Those counts are exact and independent of any ordering. ## Assembling the signed sum The sets overlap - a placement that uses only bucket 1 avoids buckets 2 and 3 at once, so it appears in several of the avoided-bucket counts - which is exactly what the alternation repairs: `onto(n, k) = sum over j from 0 to k of (-1)^j C(k,j) (k-j)^n` Worked for `n = 5`, `k = 3`: | j | C(3,j) | (3-j)^5 | signed term | |---|---|---|---| | 0 | 1 | 243 | +243 | | 1 | 3 | 32 | -96 | | 2 | 3 | 1 | +3 | | 3 | 1 | 0 | 0 | | total | | | **150** | A placement that uses only one bucket - say everything into bucket 1 - is subtracted twice by the `j = 1` group (once as avoiding bucket 2, once as avoiding bucket 3) and added back once by the `j = 2` group, so it is removed exactly once, as it should be. That is the alternation doing its job on a case you can check by hand. ## Two independent cross-checks 1. **Partition form.** Onto placements equal `k!` times the number of ways to split `n` records into `k` unlabelled non-empty groups, because naming the groups afterwards multiplies by `k!`. For `n = 5, k = 3` the unlabelled split count is 25, and `25 x 6 = 150`. 2. **Small case by hand.** For `n = 3, k = 2` the formula gives `8 - 2 x 1 = 6`, which is all eight placements minus the two that dump everything into one bucket. Enumerable in seconds, and a fast way to check you have the signs the right way round. ## Boundaries worth stating out loud - **If `n < k`, the count is zero**, and the formula produces zero on its own - no special case is needed. Some buckets must go empty when there are not enough records. - **If `n = k` it reduces to `n!`**, the assignments that put exactly one record in each bucket. - **Named versus unnamed buckets** is the distinction that most often breaks an answer. This formula counts placements into *distinguishable* buckets. If the buckets are interchangeable - an anonymous partition into `k` non-empty groups - divide by `k!`. - **Distinct versus identical records** matters just as much. If the records were interchangeable tokens, this is a completely different and much smaller count, and the exponential `k^n` would be wrong from the first line. ## Cost and why it is mild The sum has only `k + 1` terms, one per number of avoided buckets, because all `C(k,j)` subsets of the same size share a term value. That is the happy case of inclusion-exclusion: symmetry collapses `2^k` subsets into `k+1` groups. When the conditions are **not** symmetric - filters with different, unrelated match counts - no such collapse exists and the full `2^k` terms remain. Recognising which case you are in is what separates a formula-recall answer from an understanding one. ## Where it shows up Coverage counting underlies questions like how many distinct routings exercise every partition, or how likely a random assignment is to leave a consumer idle: divide the onto count by `k^n`. For `n = 5, k = 3` that is `150/243`, about 62 percent - so nearly two random routings in five would starve some bucket, which is why real routers assign deliberately rather than at random.
- Why does this sum need only k+1 terms when the general principle needs 2^k?Because the conditions are symmetric: every set of `j` avoided buckets yields the same count `(k-j)^n`, so all `C(k,j)` subsets of one size collapse into a single term. When the conditions have unrelated sizes - arbitrary filters over a data feed - no such collapse exists and all `2^k` intersection sizes must be measured separately.
- What changes if the buckets are interchangeable rather than named?Divide by `k!`. The formula counts placements into distinguishable buckets; an anonymous partition into `k` non-empty groups treats any relabelling as the same object. For 5 records and 3 buckets, `150/6 = 25` unlabelled partitions. Getting this wrong by a factor of `k!` is the most common error in coverage counting.
- What does the formula give when there are fewer records than buckets?Zero, without any special-casing. With `n < k` at least one bucket must go empty, and the alternating terms cancel to exactly zero. It is a useful smoke test on an implementation: if `n = 2, k = 3` returns anything but zero, a sign or a binomial coefficient is wrong.
saying these in an interview costs you the question
- Answering k^n and ignoring the no-empty-bucket constraint
- Subtracting the empty-bucket cases once without adding any back
- Treating named buckets as interchangeable, losing a factor of k!
- Assuming the sum needs 2^k terms even when the conditions are symmetric
- Special-casing n below k instead of letting the sum return zero