Push through a ticket barrier on the Underground and it does something oddly clever with almost no brain at all. It sits locked. Tap a valid card and it unlocks. Push through, and it locks again behind you. Tap again without pushing and nothing changes; shove a locked barrier and it stays firmly shut. The whole behaviour of the machine is captured by just two situations it can be in — locked or unlocked — and a handful of rules for how a card-tap or a push moves it between them.
That is a finite state machine (FSM): an abstract model of a system that reacts to a sequence of inputs. It has a finite set of states (the situations it can be in), one special start state, and a set of transitions — rules of the form "if I am in this state and I read that input, I move to that state." Nothing more. There is no memory of the past beyond the single state the machine is sitting in right now.
FSMs are everywhere in computing precisely because they are so cheap and so predictable: traffic lights, vending machines, the lexer that chops your program into tokens, the pattern-matcher behind a regular expression, the AI in a simple game, a network protocol handshake. Once you can see the states and the arrows between them, a surprising number of "reactive" systems become easy to reason about.
Every finite state machine is built from the same small set of parts. Fix these in your head and you can read any FSM in the world:
Some FSMs also have one or more accepting (final) states, drawn as a double circle. These matter when we use an FSM as a recogniser: feed it a whole sequence, and if it finishes in an accepting state we say the machine accepts that sequence — otherwise it rejects it. The barrier has no accepting state (it just runs forever); the binary example further down does.
The picture below is a state-transition diagram for the ticket barrier. Two states, two inputs, and four transitions — one for every combination of "which state am I in?" and "what did I just read?". Step through it and watch the machine react.
Read it out loud and it is just common sense: from Locked, a card unlocks you and a push does nothing (it loops back to Locked); from Unlocked, a push takes you through and re-locks the barrier, while another card is wasted (it loops back to Unlocked). Notice the crucial property: from every state, every possible input has an arrow. The machine is never caught not knowing what to do.
A diagram is lovely for seeing the shape of a machine, but for a computer — or for a machine with many states — a state-transition table says exactly the same thing more compactly. Each row is a current state, each column is an input, and the cell is the state you move to. The diagram and the table are two views of one identical machine.
| Current state | Input: card | Input: push |
|---|---|---|
| Locked (start) | Unlocked | Locked |
| Unlocked | Unlocked | Locked |
Every cell is filled in — there are no gaps. That completeness is what makes an FSM deterministic: given the current state and the next input, the next state is never in doubt. Trace the input sequence card, push, push, card across the table starting from Locked and you will land on: Unlocked → Locked → Locked → Unlocked. The machine's entire response to that sequence is decided the moment you know the rules.
Here is where the accepting state earns its keep. This FSM reads a binary string one bit at a
time (its alphabet is
Watch how the machine slides between states. A
| Current state | Input: | Input: |
|---|---|---|
| S0 (start) | S1 | S0 |
| S1 | S1 | S2 |
| S2 (accepting) | S1 | S0 |
Let's trace
It never stores the two bits. Instead, the identity of the state itself is the memory: each state is a summary of everything that matters about the past. S1 means "the most recent bit was a 0" — we do not care what came before it, because for the question "does it end in 01?" nothing before the last bit can matter. This is the deep trick of FSM design: choose your states so that each one packages up exactly the history you still need, and no more. Get the states right and the arrows almost draw themselves.
Because the table is the machine, translating an FSM into a program is almost mechanical: keep
a state variable, then loop over the inputs looking each transition up in the table.
Here is the "ends in 01" recogniser written out — feed it a string of bits and it reports accept or
reject.
Notice how little code it takes. The machine has no counters, no arrays of history — just a single
state that is overwritten on every bit. That frugality is the whole appeal of the model.
The FSMs so far only accept or reject. Many real machines also need to do something — a traffic light must actually show a colour, a vending machine must actually dispense a can. FSMs with output come in two classic flavours, and A-level often names both:
Both are still finite state machines — same states, same transitions — they just differ in where the output is attached (on the states, or on the arrows). A pure recogniser like our "ends in 01" machine is really just a special case with a one-bit output: accept or reject.
An FSM's only memory is the single state it is currently in. It has no notebook, no stack, no tally — just "which circle am I standing in right now." Two easy consequences trip people up: