My two year old taught me constraint solving

bambataa1 pts0 comments

How my 2yo taught me constraint solving | The Computer Science Book

Second edition with machine learning, deep learning, LLMs & AI available now!<br>Buy now

How my 2yo taught me constraint solving

08 Jul, 2026

Reading on email? The visualisations will work better in browser.

My son is two years old, which means he has an Apollonian will to power and loves all kinds of mechanised transportation and earthworks machinery. His particular joy is &ldquo;playing choo-choo&rdquo; with a Brio wooden train set. Since he likes me to be involved, but I am expressly NOT permitted to touch the trains, I amuse myself by building interesting track layouts.

After a long while, I began to think more systematically about Brio. The pieces are clearly designed to fit together into shapes, so what&rsquo;s the underlying structure in the design? Given out set of pieces, what is the most elaborate layout I can build?

I don&rsquo;t have a formal maths background, but I could see that this was an interesting algorithms problem lying on the floor in front of me. As I explored this, my son demonstrated a hitherto undetected expertise in constraint solving. The rest of this post is a lightly editorialised account of what he told me.

The Brio system

Brio is a wooden train toy for kids but has been documented in depth by particularly interested adults. I first turned to the unofficial Brio track guide, which gives every piece a letter code and a measurement. A is the 144 mm medium straight. A1 and A2 are 108 mm and 54 mm variants. E is the standard curve, an eighth of a circle, measuring just over 182 mm on the inner edge and 222 mm on the outer. Eight of those 45-degree curves therefore enclose a circle about 40 cm across. Most pieces can be flipped over, so a curve can bend left or right depending on how you arrange it.

A simple Brio layout

You get ramps and bridges too, but let&rsquo;s ignore them and treat the system as two dimensional for simplicity. This suits me because the bridges are quite rickety and my son keeps knocking them over, so I try to hide those pieces.

First, make the track close

One morning I begin by putting eight curves together to form a circle.

&ldquo;Circle!&rdquo; my son cheers.

Good! Reading Shapes with Thomas the Tank Engine and his Friends for hundreds of times has paid off.

But this is the simplest possible closed Brio loop. Where do we go from here? What sounds fun to me is to take a set of track pieces and find whether every one of them can be arranged in a closed layout (i.e. with every connector paired up).

This post features visualisations powered by three solvers of increasing sophistication. Figures one to four run a backtracking search, figure five uses constraint solving, and figure six uses a SAT solver.

The backtracking search builds the track the way a toddler would: put down a piece, look at the open connectors, try another piece, back up when something doesn&rsquo;t fit. Here&rsquo;s how we&rsquo;d make a loop:

1. Train go round

8 E curves

Slack

Step

Auto

Reset

Pieces on the floor

Search trace

0pieces placed

0.0selapsed

0states explored

0open connectors

Current choice

No track placed yet.

This visualization needs JavaScript. The solver's result for the default<br>set of pieces is an eight-piece closed circle of 45-degree curves.

Actually, my son throws the choo-choo in a rage when the track doesn&rsquo;t fit, but the solver performs recursive backtracking instead, a common way to explore a search space for those with self-control.

The open connectors form a task list. The solver works on just one of them at a time, trying every piece and orientation that fits there and recursing into each. When a branch hits a dead end — no piece that can fit, or every piece used up while connectors are still open — it backs up to the last connector that still had options. The track only counts as closed once no connectors remain open and every piece in the set has been placed. Closing early with pieces still spare is treated as another dead end to back out of. In Python-style pseudocode, it would look something like:

def search(open_connectors, unused_pieces, layout):<br>if not open_connectors:<br>return layout if not unused_pieces else None

connector = open_connectors[0]<br>for piece in unused_pieces:<br>for port in piece.ports:<br>placement = mate(piece, port, connector)<br>if collides(placement):<br>continue<br>found = search(update(open_connectors, placement),<br>unused_pieces - piece,<br>layout + placement)<br>if found is not None:<br>return found<br>return None

With eight E curves, the problem is pretty trivial as long as you lay every curve facing the same direction. The solver doesn&rsquo;t know that, though. If you step through the figure above and watch the &ldquo;states explored&rdquo; count, it will jump up very quickly. That&rsquo;s because the search first tries a curve bending the wrong way, following that dead end until it runs out of pieces without ever closing, then backing out and laying the...

piece pieces rsquo track brio search

Related Articles