Tldr
The domicule solvers and every modular solver in Lattice Dimers scan the board one cell at a time and keep, for each pattern of covered cells ahead of the scan, the number of ways to reach it. The BigInt domino and cylinder solvers step a row at a time with the same transfer matrix, and the domino formula solver evaluates a closed form. Gluing the left and right edges turns a rectangle into a cylinder, gluing the top and bottom as well makes it a torus, and only the boundary rule changes. The counts outgrow machine integers early, so the arithmetic is either exact big integers or residues modulo primes.
A domino covers two cells that share a side. A tiling lays dominoes on a board so that every cell is covered exactly once, which makes it a perfect matching of the grid graph. A domicule covers two cells that share a side or only a corner, so a domicule tiling is a perfect matching of the king’s graph, where every cell is joined to its eight neighbours. The board has 3 domicule tilings: two use straight pieces and the third uses two diagonal pieces that cross. The board has 12,988,816 domino tilings and 3,263,262,629,905 domicule tilings.
The scan
Cells are processed in row-major order. A cell is either covered already or it is matched to a later neighbour: the right one or the one below for a domino, and also the down-left and down-right ones for a domicule. The state records which of the cells ahead are covered. A domicule can reach a cell places ahead, so its state has bits, four times as many states as the domino scan with . After the last cell the count is the weight of the empty state.
from collections import defaultdict
DOMINO = [(0, 1), (1, 0)]
DOMICULE = [(0, 1), (1, -1), (1, 0), (1, 1)]
def count(h, w, moves):
states = {0: 1}
for r in range(h):
for c in range(w):
nxt = defaultdict(int)
for mask, n in states.items():
if mask & 1:
nxt[mask >> 1] += n
continue
for dr, dc in moves:
r2, c2 = r + dr, c + dc
if not (0 <= r2 < h and 0 <= c2 < w):
continue
k = dr * w + dc
if not (mask >> k) & 1:
nxt[(mask | 1 << k) >> 1] += n
states = nxt
return states.get(0, 0)This sketch is not the repository’s code. It reproduces the numbers the solvers give: count(2, 2, DOMICULE) gives 3, count(8, 8, DOMINO) gives 12988816 and count(8, 8, DOMICULE) gives 3263262629905.
A row is cell steps. Chained, they form the row transfer matrix , which acts on the sets of cells of the next row that the current row already covers. A strip of rows has tilings, with the empty state. The cost grows with the shorter side, so the domino solver turns the board until the shorter side is the row width.
Rectangle, cylinder, torus
The surface decides what happens at the edges of a row and after the last row.
| surface | glued edges | how the count is read |
|---|---|---|
| rectangle | none | the weight of the empty state after the last cell |
| cylinder | left and right | the same entry of , with neighbours taken modulo |
| torus | left and right, top and bottom | the trace of in the row form; in the cell form a sum over the first-row sets |
On a cylinder a piece can cross the seam between the last and the first column. A domicule from the first column to the last column of the next row lies cells ahead, outside the window, so for the state carries one extra bit until the scan gets there.
On a torus the cell scan runs once per set of first-row cells covered from the last row, starts from and has to end with . Rotating the columns maps the runs of onto those of its rotations, so one run per rotation class is enough. Small circumferences have two quirks. On a ring of two cells a cell meets its right and its left neighbour in the same cell, each such edge counts as a separate piece, and one row of two cells has 2 tilings. A row of odd circumference has an odd number of cells, so the counts vanish at odd heights.
Naming the solvers
Every solver id has the form <pieces>-<surface>-<method>.
| segment | values | meaning |
|---|---|---|
| pieces | domino, domicule, all-lattices | the piece, or one solver for the square lattice, the triangular lattice and the king’s graph, picked with --lattice |
| surface | rectangle, cylinder-torus | the glued edges; one solver covers cylinders and tori |
| method | formula, bigint, number, modular, polynomial-modular, polynomial-bigint | closed form; scan with BigInt counts; scan with JavaScript numbers; scan modulo primes; the last two count by the number of diagonal pieces |
The README lists 13 algorithms, each implemented in Rust, Python and JavaScript. Algorithms whose ids differ only in the method count the same boards, and a test fails when such twins disagree on a count.
Why the counts need big integers
Dominoes have a closed form. Kasteleyn and Fisher found in 1961 that the board has
tilings. Evaluated with floating-point cosines the product keeps a relative error near and loses its last digits from on, because the count has more than 16 digits by then. The solver evaluates it exactly instead. The numbers are the roots of a monic integer polynomial of degree , and the double product is, up to sign, the resultant of and :
The resultant is the determinant of an integer matrix, and fraction-free Bareiss elimination keeps every intermediate value an integer. That is also the one-line PARI/GP program of OEIS A004003.
For the king’s graph no determinantal formula is known (why), so the scan is the method. The Number solver is exact only while the count stays below , which for dominoes means up to . A004003(45), the board, has 1015 digits, and the domicule count of the board has 90. Two exact routes remain: BigInt counts inside the scan, or the scan modulo primes with one reconstruction at the end (the modular solver).
Sources
- Dawid Ryłko, lattice-dimers, README: the solver table, 13 algorithms in three languages.
- Dawid Ryłko, lattice-dimers, glossary: the solver id grammar and twin algorithms.
- Dawid Ryłko, Dominoes: tilings of the 2n × 2n board: the closed form, the resultant, the
Numberlimit and the row-width rule. - Dawid Ryłko, Domicules: tilings of the 2n × 2n board: the domicule scan, its state size and the 20 × 20 count.
- Dawid Ryłko, Domicules: tilings of cylinders: the seam bit and the small circumferences.
- Dawid Ryłko, Domicules: tilings of the 2n × 2n torus: the sum over first-row sets and the rotation classes.
- Dawid Ryłko, The dimer entropy of the king’s graph, Zenodo: the row transfer matrix and its state space.
- Dawid Ryłko, lattice-dimers, A004003 entry notes: the digit count of the 90 × 90 board.
- OEIS Foundation, A004003: domino tilings of the 2n × 2n square.
- P. W. Kasteleyn, The statistics of dimers on a lattice, Physica 27, 1961.
- M. E. Fisher, Statistical mechanics of dimers on a plane lattice, Physical Review 124, 1961.
- E. H. Bareiss, Sylvester’s identity and multistep integer-preserving Gaussian elimination, Mathematics of Computation 22, 1968.