Bricks
Consider the standard 8-post LEGO brick[1], and the tiling puzzles we might make with it.
This brick is twice as long as it is wide. It is a domino - a 2x1 rectangle that can tile rectangular regions in many ways[2]. But it doesn't have two posts[3] on top, it has eight, and eight corresponding holes on the bottom. This means it can be stacked at half-unit offsets, which creates elegant ledges/parapets.
Pyramids
One brick can be set on a slightly larger base of three bricks, creating a half-unit ledge that goes around the perimeter. That in turn can be rested on a base of six bricks, and so on. This forms a slightly oblong pyramid[4]. This shape is simple to understand and straightforward to scale up, which makes it easy to reason about.
Pyramids have some nice properties: the area of every level is even (they can all be tiled with dominos), and every integer evenly divides the area of some two adjacent levels. If you are trying to assemble polycubes of volume seven into a simple shape, you might end up here.
| Pyramid Layer | Dimensions | Area | Bricks | Total |
|---|---|---|---|---|
| 1 (top) | 1x2 | 2 | 1 | 1 |
| 2 | 2x3 | 6 | 3 | 4 |
| 3 | 3x4 | 12 | 6 | 10 |
| 4 | 4x5 | 20 | 10 | 20 |
| 5 | 5x6 | 30 | 15 | 35 |
Constraints
Domino tilings are under-constrained: as a rectangle grows the number of ways to tile it grows quickly. If we want a puzzle to have a unique solution we need an additional constraint.
Here are the constraints we already have:
- Bricks must fill some fixed volume without gaps or overlap.
- Bricks must align to a lattice grid (allow a half-unit offset).
- Bricks must be oriented posts up, holes down.
Within these constraints, the matching rules for touching faces don't constrain brick placement:
| post | hole | blank | |
|---|---|---|---|
| blank | never happens | never happens | ✅ (side-side) |
| hole | ✅ (top-bottom) | never happens | |
| post | never happens |
Modified Bricks
We can modify a brick by removing some of the posts and holes, replacing them with blanks (flat surfaces). We end up with something like this:
From here on, brick refers to one of these modified 8-post LEGO bricks.
With this modification we need to explicitly state a new constraint:
- If a brick is placed on top of another, posts of the bottom brick must line up with holes of the top one where they touch.
Now the matching rules do constrain brick placement, because a post can't fit into a blank:
| post | hole | blank | |
|---|---|---|---|
| blank | ❌ | ✅ | ✅ |
| hole | ✅ | never happens | |
| post | never happens |
Puzzle Concept
The puzzle idea is this: the player gets many copies of a certain brick. They use them all to build an oblong pyramid shape[5].
My goal with this project is to evaluate every possible brick, and find one that would make this a good puzzle. Ideally, for that brick and some reasonable pyramid size, there will be a single solution that is possible and fun to discover.
Because we are looking for a puzzle with a unique solution, much of this page focuses on ruling out bricks that always have zero or multiple solutions.
Representing Bricks
There are 8 posts and 8 holes to remove or keep. 16 binary decisions means 65,536 bricks to evaluate.
With so many candidates, it's useful to have a short identifier. We'll represent each brick with a 4-digit hex code.
- Convert the upper row of four post positions to a sequence of 0s (blanks) and 1s (unmodified posts). Convert this 4-digit binary number to hex to be the first hex digit (0-F).
- Convert the lower row of post positions to the second hex digit.
- Convert the upper row of hole positions to the third hex digit (0s are blanks, 1s are unmodified holes).
- Convert the lower row of hole positions to the fourth hex digit.
All sequences are read left to right with the brick viewed from above[6].
So, for example:
- FFFF is the unmodified 8-post LEGO brick.
- 0000 is a smooth box with no posts or holes.
- FF00 has 8 posts on top and a smooth bottom.
- 00FF has a smooth top and 8 holes on bottom.
- 134E has 3 posts and 4 holes.
- 4E13 has 4 posts and 3 holes.
Candidate Map
Let's map out the brick candidates. Every brick is one small square on the grid below.
Down is the code's first two digits (the "+" post markings on the top). Across is its second two (the "-" hole markings on the bottom).
Some bricks are rotations/reflections of others, so we need to define a canonical form. A brick code is canonical when it is the lowest hex value describing the same physical brick.
The banding is horizontal because a code sorts on its first two digits first, so the top-face byte alone usually decides the whole row: 54 rows are solid blue (that byte is already the lowest of its own four orientations, so every code in the row survives), 180 are solid black (it never is), and only the remaining 22 are speckled — those are the bytes that tie with one of their own orientations, leaving the bottom-face byte to break it column by column.
Parity
The same grid as above, but with each cell tinted lighter for an even number of posts+holes. Rotation and reflection only move markings around, so duplicate forms of the same brick have the same tint.
Parity changes frequently, so the tinting pattern is too noisy to be useful.
Sort by Count
Here the tinted grid is re-arranged: rows are ordered by the number of posts, and columns by the number of holes.
Bricks with the same number of posts and holes form large rectangular regions of constant tint; duplicate forms are always in the same region.
Rearrangement clarifies some patterns and obfuscates others. It's easy to visualize the most common post/hole count (4/4, the center square region). But the speckled 55xx row had a clear pattern in the first grid and appears as noise here.
Omit Duplicate Rows
This grid hides the all-duplicate rows.
Speckled rows only occur when there are an even number of posts.
No Unique Solutions
We are looking for a puzzle with a unique solution, so we can exclude combinations of bricks and pyramid boards that can be proven to never have exactly one solution. In some cases we don't determine if there are 0 or 2+ solutions, we just rule out 1.
Bricks with more posts than holes (teal) can't be eliminated yet, but they won't have multiple solutions forever. They all run out of solutions by pyramid23.
Square Coverage Part 1
Every tiling of size N>1 contains a square[7]: a 2x2 block filled by two parallel bricks. Three things can go wrong with a square:
Quarter-Turnable Sometimes the posts on top of a square form a pattern with 90º rotational symmetry. When that square sits in the bottom layer, it can be turned 90º in place, forming a second, distinct solution.
Half-Turnable Sometimes the posts on top of a square form a pattern with 180º rotational symmetry. On the bottom layer, it can be turned 180º in place. If its holes are not 180º symmetrical this forms a second, distinct solution.
Untoppable Sometimes there is no legal way to place bricks in the layer directly above a square. The square may lie on an edge but the layer above must have at least one brick that covers 6/16ths of the square's area, including the middle 4/16. If the upper brick can't, the square is not toppable and the puzzle has no solution.
When all square configurations meet one or more of these conditions, the brick can be eliminated: on any N>1 pyramid, there will be either no solution or more than one.
Two-Level Pyramid
Here we use brute force, and check every way to tile a two-level pyramid with every remaining brick.
Three-Level Pyramid
Here we tile a three-level pyramid with each remaining brick.
Fingerprinting
See Layer Groups for more on fingerprints.
Square Coverage Part 2
For N>3, every domino tiling of an Nx(N+1) board contains a non-corner square[7:1]. So now a rectangle of 12 of the square's 16 top posts must be coverable by bricks one layer above.
Four-Level Pyramid
Here we tile a four-level pyramid with each remaining brick.
Five-Level Pyramid
Here we tile a five-level pyramid with each remaining brick.
This is the first time all tilings contain an interior brick. Until now, bricks like 1104 could hide their pegs on the outer edge to avoid any meaningful interaction with pieces above.
Square Coverage Part 3
For N>5, every domino tiling of an Nx(N+1) board contains a center square[7:2]. So all of the square's 16 top posts must be covered by bricks on the layer above. "turn or untoppable"
There is a second way to eliminate bricks: enumerate every hole/blank pattern that could be above a center square — and for each, count how many distinct 2-brick squares of this brick (differing in orientation, pegs, or holes) could sit under it with every peg meeting a hole. If no such pattern admits exactly one square, the brick can be eliminated: either no square fits (no solution) or 2+ do (multiple solutions). "no lone fitting square"
Singletons So Far
Here each brick with a singleton solution gets a unique color; other cells adopt the color of their nearest singleton neighbor.
Singleton bricks by hole surplus (holes minus posts) and symmetry (whether top and bottom are half-turn symmetrical).
The Frontier
The bricks we are still exploring.
Frontier bricks by hole surplus and symmetry.
Solve Singletons
Click the button below to save every brick/board combination found so far that has exactly one solution (the green cells above). These will be bundled into a puzzle series which can be reviewed or solved.
Selected Brick
This is most iconic LEGO brick to me and the one illustrated in their original patent. LEGO now refers to it as Part 3001. I was surprised to see it listed as only the 34th most common LEGO part in sets released 2021-2025. ↩︎
Domino Tiling on wikipedia ↩︎
LEGO seems to use the terms “stud” and "tube". I'm calling them posts and holes. ↩︎
See also Pyramid of Djoser ↩︎
Try this out on the Brick Puzzles page: enter a brick's hex code to generate a puzzle for each pyramid size, which you can then try solving. ↩︎
Let's say the viewer has xray vision and can see holes through the brick. ↩︎
See further analysis in Squares in Domino Tilings ↩︎ ↩︎ ↩︎