Books · Problem of the Week: Solutions
Chapter 1
Losing Tic-Tac-Toe
Stan Wagon’s Problem of the Week 1416 shows six black squares on a grid and asks you to read them as queens on a chessboard. No three of them lie on a common queen-line, where a queen-line means a row, a column, or a line at . The configuration is stuck: put a queen on any of the thirty empty squares and some queen-line acquires three. The right-hand board below adds one, and a diagonal duly picks up a third.
The problem then asks for the same thing one size up. It is worth being careful about what “the same thing” means, because the answer turns on it, and because the version as posed cannot be done.
The model
Number the squares with the row and the column, both running from to . Every square lies on exactly four queen-lines, and each of the four is a level set of a simple function:
| its row | is constant |
| its column | is constant |
| its diagonal | is constant |
| its anti-diagonal | is constant |
The third and fourth lines are the useful ones. A line looks like a geometric object, but “three squares lie on a common line” says nothing more than “three squares share a value of ”, or of . Collinearity at is arithmetic. That is the whole reason this problem is finite and checkable: an board has rows, columns, diagonals and anti-diagonals, so has queen-lines and nothing else to consider.
Now fix a set of marked squares and impose the two conditions.
Safety. No queen-line contains three marks. Equivalently, every queen-line contains at most two.
Maximality. Adding a mark on any empty square creates three on some queen-line.
Maximality looks like the awkward one, since it quantifies over every empty square and every line through it. Safety tames it. Call a queen-line full when it carries exactly two marks, which by safety is as many as it may carry. Adding a mark at an empty square creates a three only if the new three includes , since the old marks were already safe. So the new three lies on one of the four queen-lines through , and that line must already hold two marks. Turning this round:
Let be safe. Then is maximal if and only if every square not in lies on a full line.
The quantifier over added queens is gone, replaced by a covering condition on lines. This is the form to think in, and the form to compute in.
Twelve on a board is impossible
Wagon’s problem asks for twelve marks on a board. No such configuration exists, and the reason is worth more than the answer.
Write for the number of marks. Call a row or column full if it holds two marks. Let Everything follows from one observation about .
is exactly the set of squares whose row is not full and whose column is not full. So if counts the non-full rows and the non-full columns, is a combinatorial rectangle with , and each non-full column contributes exactly squares to it.
This is immediate from the definition, and it is the crux. The two conditions defining are independent, one about and one about , so inherits a rigid rectangular shape no matter how the marks are scattered.
Step 1: is large
Let count the marks alone in both their row and their column. Each full row holds two marks, and neither is one of those . So , giving at most full rows out of fourteen, and therefore with the same bound for . At least eight rows and eight columns are non-full. Twelve marks are simply too few to make many rows full: each full row costs two of them.
Step 2: the extreme columns
Let be the first and last non-full columns, and the first and last non-full rows. Assume ; if not, rotate the board by , which exchanges rows with columns and diagonals with anti-diagonals, leaving both conditions and every count intact. By the lemma, column carries squares of and so does column : call them and , with .
None of these squares sits on a full row or a full column. So each is either occupied by a mark or killed by a full line. Column is not full, so it holds at most one mark, and likewise column : at most two of the squares are occupied. Moreover an occupied one lies in a non-full row and a non-full column, which then hold no other mark, so it is alone in both and is counted by . At most of the squares are occupied.
Step 3: diagonals are inefficient
A line meets a column once, so it kills at most one square of and one of . Suppose one kills two, at and . Going from column to column moves steps sideways, so . But and both lie in , forcing . With the assumption of Step 2 this pins , and then and are pinned to the ends: the line is a diagonal of the rectangle . There is one such line of each slope, and every other line kills at most one of the squares.
Let count the full diagonals and anti-diagonals. Now account for the squares of . At most are occupied. The two rectangle diagonals kill at most two apiece, so at most four between them. Each of the remaining lines kills at most one. Hence so, using from Step 1, The cancels, whichever value it takes.
Step 4: there are not enough diagonals
Each full diagonal uses two of the twelve marks, so there are at most six, and at most six anti-diagonals: Step 3 demands . This is a contradiction, so no such configuration exists. 0■
Nothing used the number except through the arithmetic. Run the same count on an board with marks and it yields for every even . The reader who wants the odd case, and a second proof by the Combinatorial Nullstellensatz, should see Cooper, Pikhurko, Schmitt and Warrington, whose Theorem 1 this is.1
What the problem meant
The minimum number of marks on an board is written . The full theorem of Cooper et al. gives for every except , where one less may suffice. A twelve-mark configuration therefore forces : the only board the exception could rescue is , and . And exactly. So the honest reading of Wagon’s problem is a board, not , and the provenance agrees: Gardner’s October 1976 column recorded placements on boards from up to .2 The alternative repair, fourteen marks on , is also impossible: , so the smallest maximal configuration on that board carries fifteen marks.3
Here is a answer.
It is prettier than the case deserves. The twelve squares carry the full symmetry of the square, invariant under both reflections, under the half-turn, and under transposition. They form three nested rectangles: the four corners, and two rectangles exchanged by transposition.
Maximality is visible rather than asserted. Draw every full line, and the empty squares have nowhere to hide.
The count is tight here
The pleasing part is that the argument that killed does not merely permit , it is satisfied with nothing to spare. Run Step 1 through Step 3 with and . No mark is alone in both its row and column, so , and there are six full rows, so . Step 3 then demands Counting the figure: five full diagonals and five full anti-diagonals, so . Exactly ten. The configuration sits on the boundary of the inequality, which is why twelve marks fit on twelve columns and not on fourteen. On a board the same marks would leave two more rows and two more columns non-full, the extreme columns would carry sixteen exposed squares instead of twelve, and the demand would climb to fourteen diagonals against a supply of twelve.
On computing
The proof above needs no machine. Finding the configuration does, and the two tasks want different tools.
The covering form of the Proposition translates directly into a constraint model. For each square a Boolean , and for each queen-line a Boolean meaning “ is full”:
for cells in lines.values(): # safety
model.Add(sum(x[c] for c in cells) <= 2)
for key, cells in lines.items(): # f <=> line is full
model.Add(sum(x[c] for c in cells) >= 2).OnlyEnforceIf(f[key])
model.Add(sum(x[c] for c in cells) <= 1).OnlyEnforceIf(f[key].Not())
for (i, j) in squares: # maximality
through = [("row", i), ("col", j), ("dia", i-j), ("ant", i+j)]
model.Add(x[(i, j)] + sum(f[k] for k in through) >= 1)
Two details earn their keep. The second constraint is redundant for correctness, since appears only positively in the third block, but making a genuine indicator rather than a one-way implication is what lets the solver propagate; without it the case does not resolve in reasonable time. And the whole model rests on reading the lines as level sets of , which is what makes the line index finite.
Solved for and , this returns the configuration above in about a third of a second. Its output can be checked against the published values of for , namely , and it reproduces all ten, including the irregular .
The contrast with the proof is the lesson. A solver reports that twelve marks on is infeasible after half a minute of search, and that verdict covers one board and explains nothing. Four paragraphs of counting dispose of every even board at once, and say why: the squares that escape the full rows and columns form a rectangle, the two extreme columns of that rectangle expose of them, and lines can only pick them off one at a time.
Lines of any slope
Queen-lines are a convention. Drop it, and say three squares are in a row when their centres lie on one straight line of any slope, so that , and now count. Both conditions move at once. Safety tightens, since triples the queens game ignored are now fatal. Maximality loosens, since an empty square can be caught by any line through it rather than by four. Nothing so far says which effect wins.
The Proposition survives word for word, with “line” now meaning a maximal set of three or more collinear squares. The problem stays finite, though no longer small: a board carries such lines, and only of them are queen-lines.
Both boards above pass into the new game unchanged. No three of Wagon’s six queens are collinear on any slope, and every empty square of the board is collinear with two of them; the machine confirms the same for the twelve marks on . Neither solution leaned on the convention.
The impossibility proof does not survive. Its engine was scarcity: in the queens game a full line needs two marks already aligned on a row, a column or a line, and twelve marks can make at most six full diagonals and six full anti-diagonals. Here every pair of marks spans a full line. Twelve safe marks carry of them, all distinct, since a shared line would hold three marks. And Step 3 dies with the scarcity: a line meeting both extreme columns of is no longer forced to climb one row per column, so it need not be a diagonal of the bounding rectangle, and tilted lines can kill exposed squares two at a time. The count never gets started.
The conclusion reverses with it. Twelve marks fit on a board once every slope is in play.
The structure rhymes with the answer. The four corners return, and in place of two nested rectangles an octagon rings the centre, and , exchanged by transposition. Verification is the direct kind: none of the triples of marks is collinear, and each of the empty squares is collinear with two marks. Eight of those squares, the orbit of under the symmetries of the board, are caught by tilted lines alone. That is the theorem of the earlier sections showing through: had every empty square sat on a full queen-line, these twelve marks would contradict the count of Steps 1 to 4.
The minimum for this game is tabulated as OEIS A277433. For it runs , against for the queens game: never larger, despite the harder safety condition. The extra lines help more than they hurt, and the queens bound is not merely unproved here but false, since eight marks suffice on . The exact values stop at , completed by Aichholzer, Eppstein and Hainzl, who also prove that fewer than order marks can never suffice. Twelve is the best known count for both and , so the octagon configuration is best known rather than best possible.4
The constraint model is the one already given; only the table of lines changes, lines of every slope in place of the queen-lines. Asked for twelve marks carrying the full symmetry of the square, the solver produces the octagon in a tenth of a second.
The sixteen symmetric solutions
A solver can do better than produce an answer. Asked to enumerate rather than to find, it reports that the twelve-mark solutions with the full symmetry of the square number exactly sixteen, lists them in the same tenth of a second, and every one of the sixteen passes the direct check of triples and coverage.
The count is not merely observed, it can be proved, and most of the proof is done by hand. The symmetries of the board split its squares into orbits. An orbit seeded on the main diagonal, at with , has size four; every other orbit has size eight, with a unique seed satisfying . A fully symmetric solution is a union of orbits, and twelve splits as or . The second dies at once: three diagonal orbits put six marks on the main diagonal, and any three of those are collinear. So every solution is one diagonal orbit and one ring, which leaves candidates. What remains is finite checking, and no solver is needed for it: run the cross-product test over the , and fail safety, more fail maximality, and the sixteen of the figure survive. The CP-SAT enumeration returns the same sixteen, so the census rests on nothing deeper than integer arithmetic that agrees with itself twice.
The catalogue has its own small structure. Four diagonal orbits occur, seeded at , , and , the last being the central block . Nine distinct rings partner them, the corners taking six, the block only two, and the ring seeded at alone is compatible with all four diagonal choices.
The census also travels back to the queens game, where the paper began. On the board the same orbit argument leaves candidates, and the queen-line test passes exactly eight. The solution of the earlier section is the second; the eighth builds on the central block , the same germ as number 16 above. Five of the six diagonal orbits appear, and only the seed partners no ring at all. The CP-SAT enumeration over queen-lines returns the same eight.
Wagon’s twelve and fourteen were the right numbers for a game one convention away, and the game repays the widening sixteen times over.
Appendix: the programs
Every computed claim in this paper rests on the programs below: the table of lines, the model with its enumeration, a check that trusts nothing but cross products, the census of the sixteen, and the one-predicate substitution that makes it a census of the eight. They need ortools and the standard library, and the checks only the standard library.
from itertools import combinations, product
from math import gcd
from ortools.sat.python import cp_model
A line of any slope is recorded as its maximal run of grid squares, walked once from its first square along a primitive direction, and kept when it holds three or more. On this yields the ; restricting the directions to , and recovers the queens game.
def grid_lines(n: int) -> list[list[tuple[int, int]]]:
dirs = [(0, 1), (1, 0)]
for dx in range(1, n):
for dy in range(1, n):
if gcd(dx, dy) == 1:
dirs += [(dx, dy), (dx, -dy)]
lines = []
for dx, dy in dirs:
for i, j in product(range(1, n + 1), repeat=2):
if 1 <= i - dx <= n and 1 <= j - dy <= n:
continue # not the start of this line
chain, ci, cj = [], i, j
while 1 <= ci <= n and 1 <= cj <= n:
chain.append((ci, cj))
ci, cj = ci + dx, cj + dy
if len(chain) >= 3:
lines.append(chain)
return lines
The model is the one from the queens game with the bigger table, plus the two reflections that generate the symmetry group, and a callback that collects every solution instead of stopping at the first. The indicator constraints make a function of the marks, so sixteen assignments mean sixteen configurations, not double counting.
def all_symmetric(n: int, q: int) -> list[list[tuple[int, int]]]:
model = cp_model.CpModel()
board = list(product(range(1, n + 1), repeat=2))
x = {c: model.NewBoolVar(f"x{c}") for c in board}
through = {c: [] for c in board}
for k, line in enumerate(grid_lines(n)):
f = model.NewBoolVar(f"f{k}")
s = sum(x[c] for c in line)
model.Add(s <= 2) # safety
model.Add(s >= 2).OnlyEnforceIf(f) # f <=> line is full
model.Add(s <= 1).OnlyEnforceIf(f.Not())
for c in line:
through[c].append(f)
for c in board: # maximality
model.Add(x[c] + sum(through[c]) >= 1)
model.Add(sum(x.values()) == q)
for i, j in board: # dihedral symmetry
model.Add(x[(i, j)] == x[(j, i)])
model.Add(x[(i, j)] == x[(n + 1 - i, j)])
sols: list[list[tuple[int, int]]] = []
class Collect(cp_model.CpSolverSolutionCallback):
def on_solution_callback(self) -> None:
sols.append(sorted(c for c in board if self.Value(x[c])))
solver = cp_model.CpSolver()
solver.parameters.enumerate_all_solutions = True
solver.Solve(model, Collect())
return sols
No verdict rests on the model. The checker re-derives both conditions from cross products alone, safety over the triples of marks and coverage over the empty squares. A checker that cannot fail proves nothing, so it was first fed mutilated configurations, a mark removed and a mark added, and rejected both.
def collinear(p: tuple[int, int], q: tuple[int, int],
r: tuple[int, int]) -> bool:
return ((q[0] - p[0]) * (r[1] - p[1])
== (q[1] - p[1]) * (r[0] - p[0]))
def is_solution(n: int, marks: list[tuple[int, int]]) -> bool:
safe = not any(collinear(*t) for t in combinations(marks, 3))
empty = (c for c in product(range(1, n + 1), repeat=2)
if c not in set(marks))
covered = all(any(collinear(p, q, c)
for p, q in combinations(marks, 2))
for c in empty)
return safe and covered
Last, the census. The symmetry argument in the text reduces the count of fully symmetric solutions to candidates, one diagonal seed and one ring seed, and this loop scores them with the checker alone. It returns the sixteen seed pairs in a few hundredths of a second, with no solver in sight, and the figure of sixteen is drawn from its output rather than the solver’s. Two derivations that meet exactly are worth more than one derivation trusted twice.
def census(n: int = 14) -> list[tuple[int, tuple[int, int]]]:
m = n + 1
def orbit(i: int, j: int) -> set[tuple[int, int]]:
return {(i, j), (j, i), (m - i, j), (j, m - i),
(i, m - j), (m - j, i), (m - i, m - j), (m - j, m - i)}
return [(d, (a, b))
for d in range(1, n // 2 + 1)
for a in range(1, n // 2 + 1)
for b in range(a + 1, n // 2 + 1)
if is_solution(n, sorted(orbit(d, d) | orbit(a, b)))]
The queens game takes the same census. Substitute the queen-line test below for collinear inside is_solution and run census(12): ninety candidates, and the eight of the figure come back.
def queen_collinear(p, q, r) -> bool:
return (len({p[0], q[0], r[0]}) == 1
or len({p[1], q[1], r[1]}) == 1
or len({p[0] - p[1], q[0] - q[1], r[0] - r[1]}) == 1
or len({p[0] + p[1], q[0] + q[1], r[0] + r[1]}) == 1)
A. S. Cooper, O. Pikhurko, J. R. Schmitt and G. S. Warrington, Martin Gardner’s minimum no-3-in-a-line problem, American Mathematical Monthly 121 (2014) 213–221; arXiv:1206.5350. The elementary argument above is their Section 4, which follows an incomplete argument of John Harris in a letter to Gardner of 7 June 1975. Consulted 16 July 2026.↩︎
M. Gardner, Mathematical Games, Scientific American, October 1976; reprinted in Penrose Tiles to Trapdoor Ciphers, MAA, 1997, chapter 5. The range of boards is reported in the history section of Cooper et al. Consulted 16 July 2026.↩︎
Cooper et al. could print only the bounds ; the exact value was computed in 2014 by Rob Pratt by integer linear programming, and is recorded, with values up to , as OEIS sequence A219760. Consulted 23 July 2026.↩︎
OEIS sequence A277433, values and best-known bounds as revised 3 July 2026. O. Aichholzer, D. Eppstein and E.-M. Hainzl, Geometric dominating sets, Computational Geometry 108 (2023), article 101913; arXiv:2203.13170: the lower bound, and optimal configurations up to . Consulted 23 July 2026.↩︎