How long would a troop of monkeys really take to type your phrase?
Not the textbook answer. The answer for monkeys hitting an actual QWERTY
keyboard, where the space bar is enormous, Q is in a corner, a third of the
keys do nothing, and Shift has to be hit first if you want a capital.
Millions of monkeys, simulated for real in Rust and WebAssembly, next to an exact closed-form prediction of how long they will take. The two agree, which is the point.
"It's 26 to the power n." Only if every letter is equally likely, and on a
real keyboard none of them are. Key probability is a fact about where a key is
and how big it is, not about the letter printed on it. On the default model a
monkey is six times likelier to hit g than q, and the gap between its
likeliest and least likely character is a factor of 3256.
"The wait is one over the probability." No. Waiting for aaaa, you get three
as and a b and you have lost the three as too. A phrase that starts the way
it ends makes you pay for every false start twice, so aaaaaaaa takes 4% longer
than abcdefgh despite being exactly as probable. The correct formula has one
term per way the phrase overlaps itself:
E[T] = sum over k in O(w) of 1 / P(w[..k])
where O(w) is the set of lengths at which the phrase's head is also its tail.
It is derived from scratch in the paper, checked
against an independent linear solve, and checked again against brute-force
simulation.
Once you can score an arrangement of letters exactly, you can ask whether QWERTY was ever a sensible place to put them. Same keyboard, same key sizes, letters moved around, scored on held-out English prose:
| Layout | Home row | Travel | Alternation | Same finger | Effort |
|---|---|---|---|---|---|
| QWERTY | 47.3% | 0.646 | 51.2% | 8.78% | 0.734 |
| Dvorak | 75.0% | 0.372 | 70.0% | 2.93% | 0.402 |
| Minimum reach | 82.2% | 0.308 | 50.2% | 9.51% | 0.403 |
| Searched | 81.7% | 0.313 | 53.4% | 2.20% | 0.335 |
The best layout the search found. Amber keys are reached by the left hand, teal
by the right, and the white bars mark the eight resting positions. The vowels
ended up under one hand and s n t under the other — Dvorak's central idea,
arrived at by a search that was told nothing except a formula.
Dvorak's 1936 claim survives measurement comfortably. The layout that is provably optimal for finger travel is worse than QWERTY at same-finger bigrams, because travel is a per-character objective and awkwardness is a pairwise one. A search on a better objective beats all of them, rediscovers Dvorak's vowel/ consonant hand split without being told, and then fumbles hand alternation because nobody put alternation in its objective either.
Every layout here is optimal for exactly what it was told to care about, and mediocre at the first thing left out.
- The phrase. Anything the keyboard can type, capitals and punctuation included. Short ones really do get found while you watch.
- The troop. Up to 4,194,304 monkeys, each one actually simulated, each with its own typing speed drawn from a log-normal distribution shaped like real human words-per-minute data.
- Speed. Real time up to a billion times faster. When the machine cannot keep up it says so rather than quietly lying.
- The keyboard. QWERTY, Dvorak, the searched layout, or a layout optimised on the spot for your phrase.
- How they hit it. One hand aimed at the middle, or two hands resting on the home row — which turns out to move the answer by more than an order of magnitude and nearly double how often Shift gets hit.
cargo test --release # 155 tests
wasm-pack build crates/wasm --target web --out-dir ../../pkg --out-name monkeystyping
python3 -m http.server 8731 # then open http://localhost:8731Regenerate every number in the paper:
cargo run --release -p monkeystyping-core --example validatecrates/core Pure Rust, zero dependencies. All the mathematics, all the
simulation, and 134 of the tests.
crates/wasm wasm-bindgen shim. Translation only, no logic.
index.html Vanilla JS. No framework, no npm, no build step beyond wasm-pack.
crates/core has no dependencies on purpose: it means cargo test runs exactly
the code the browser runs. A monkey costs 24 bytes — a generator state, a
KMP automaton state, a personal best, a typing rate, and a work credit — so
four million of them fit comfortably in memory and a frame's typing is a tight
loop over flat arrays. Expected waiting times routinely exceed f64::MAX, so
every large quantity is carried as a base-10 logarithm and only turned into
digits at the moment it is displayed.
More in docs/ARCHITECTURE.md.
Backspace is inert, Caps Lock does nothing, aim never drifts, and the monkeys never sleep, tire, or die. The human typing metrics are geometric — no muscle memory, no anatomy, and no account of the twenty years you have already spent learning QWERTY, which in practice swamps every effect measured here.
These are stated as choices rather than hidden, and argued individually in Section 6 of the paper. Nobody should switch keyboard layouts on the strength of this.
MIT. See LICENSE and CONTRIBUTING.md.