An ordering of all bit strings where consecutive strings differ in exactly one bit. It’s a Hamiltonian cycle of the hypercube, and it lets you enumerate subsets with one insertion or deletion per step.

Reflected binary code

unsigned gray(unsigned i) { return i ^ (i >> 1); }
unsigned grayInverse(unsigned g) { for (unsigned s = g >> 1; s; s >>= 1) g ^= s; return g; }
// or in O(log w): g ^= g >> 1; g ^= g >> 2; g ^= g >> 4; g ^= g >> 8; g ^= g >> 16;
  • and differ in bit .
  • The sequence is cyclic: differs from in one bit.
  • parity of the step count , since each step flips exactly one bit.
  • Tower of Hanoi: move moves disk , the same bit that changes in the Gray code.

Enumerating subsets with updates

for (unsigned i = 0; i < 1u << n; i++) {
    if (i) { int b = __builtin_ctz(i); (gray(i) >> b & 1) ? add(b) : remove(b); }
    process(gray(i));
}

That’s single-element updates instead of . Useful when inserting or removing one element is expensive: maintaining a matrix product, a determinant via rank-one updates, a convex hull, or computing the permanent with Ryser’s formula in (Permanent).

Variants and facts

  • -ary reflected Gray code: consecutive strings differ by in one digit. Generate by reflecting digit order like the binary case.
  • Gray code over a subset lattice of fixed size (revolving door / combinations differing by one swap): enumerate all -subsets with one element swapped out and one in per step.
  • Hamiltonian cycle on with a prescribed start: XOR every code with the start.
  • Hamiltonian path in a hypercube between two vertices: exists iff they have different parity (bipartite), and a recursive construction splits on a coordinate where they differ.
  • Minimum number of single-bit flips to visit all states: , attained by Gray code.
  • Balanced Gray code: a variant where every bit position changes roughly the same number of times across the whole cycle, rather than the reflected code’s heavy skew toward the low bits. Monotone Gray code: one where the sequence of changed-bit positions follows a monotone pattern. Snake-in-the-box: the longest induced path in a hypercube (no two non-consecutive visited vertices adjacent) — an open combinatorial problem in general, unlike the Hamiltonian-cycle question Gray code answers exactly.
  • Outside CP: rotary encoders and ADCs use Gray code so a reading caught mid-transition is off by at most one step, instead of the arbitrary garbage ordinary binary gives on a multi-bit flip (e.g. ); Karnaugh maps label rows/columns in Gray code so adjacent cells differ in one variable, which is what makes the visual minimisation of boolean functions work.
  • De Bruijn sequences are the cyclic analogue for windows rather than whole strings (Euler Tours).