↑ ↓ to move · enter to open

014 · Intermediate · Math, bit tricks

the missing number

An array holds n distinct numbers taken from 0 to n, shuffled, so exactly one value is absent. You can find it in one pass with a couple of extra variables: add everything up and compare against the sum you expected, or XOR everything together and let every pair cancel itself.

LAB 1

the sum that should be there

Write 0 to n forward, then write it again backward underneath. Every column adds up to n, and there are n + 1 columns, so the two rows together hold n(n + 1) and one row holds half of that. Scan the array, subtract what you see from that total, and whatever is left over is the number that never showed up.

0 … n forward
… and backward
column sums (all n)
the array
12 7
Integer

How to read this: Top: the numbers 0 to n written forward and backward; each column adds to n (gold). Bottom: the actual array, with each position in tiny numbers above it. As each array number is read, it lights up in the top rows.

  • amber: number being read now
  • green: already counted
  • gold block: the number that never appeared

Try this: Press Step a few times and watch the Expected − total readout shrink toward the answer.

—
Expected n(n+1)/2
—
Running total
—
Expected − total
—
Additions · extra vars

This step

The codeO(n) time · O(1) space

2·S = (n+1)·n ⇒ S = n(n+1)/2

When the total overflows

Fixed-width integers cap the total. Switch to Signed 8-bit, where the largest value is 127, and push n past 10: the product n(n+1) wraps around before it is halved, and for most n the answer comes out wrong.

In Java the value wraps silently. In C and C++ signed overflow is undefined behavior. XOR never carries from one bit into the next, so its register never needs more bits than n itself. Lab 2 shows it.

LAB 2

xor makes pairs vanish

XOR every index from 0 to n into one register, then XOR every value in the array into the same register. Each present number goes in twice, once as an index and once as a value, and x ⊕ x = 0 wipes it out. The only number that went in once is the missing one, so it is all that remains. Watch the register change one bit at a time.

10 6

How to read this: Every number is written in binary: each box is 0 or 1, and the small numbers above (8 4 2 1 and so on) show what each box is worth (1010 = 8 + 2 = 10). XOR flips a register box whenever the incoming bit is 1, so two equal numbers flip the same boxes twice and cancel out.

  • green box: a 1 bit
  • amber outline: bit being processed
  • faded, crossed out: cancelled by its twin
  • gold: what's left, the missing number

Try this: Use Step number to feed whole numbers; switch to Step bit to watch single flips.

—
Register
—
Numbers XORed
—
Pairs cancelled
—
Bit operations

This step

The codeO(n) time · O(1) space

x ⊕ x = 0, x ⊕ 0 = x, order doesn't matter

Why it works

XOR is associative and commutative, so the order of the scan does not matter. You can regroup the whole chain into matching pairs, each pair collapses to 0, and 0 ⊕ m = m.

Bit by bit it is a parity count: a register bit ends at 1 exactly when an odd number of inputs had a 1 there. Every present number adds two 1s to each of its bit columns, so only the missing number's bits survive.

LAB 3

other routes, same answer

Three more ways to find the gap, run on the same input. Sorting puts every number in its slot but costs O(n log n). A seen-array is linear but needs n + 1 extra cells. Cyclic sort swaps each value into the slot with its own index, in place, and then the first slot holding the wrong value is the answer. The counters show what each route actually spends.

array
12 5

How to read this: The small numbers on top are slot numbers. A cell turns green once it holds its own slot number; the first slot that can't is the missing number.

  • amber: being compared or swapped
  • green: in the right slot
  • gold: the gap
  • ✓ value seen · · empty

All five routes on this input

  • green: best on this input
  • red: worst
  • highlighted row: the route animated above
  • arith: additions or XORs
—
Comparisons
—
Array writes
—
Extra cells
—
Answer

This step

The code

Trade-offs