Books · Solving Puzzles through Mathematical Programming
Chapter 6
Drive Ya Nuts
Seven hexagonal nuts sit on a plastic base of seven pegs. Each nut carries six numbered edges; the numbers through appear in some order around each nut’s perimeter. The base is a flower: one peg at the centre, six around it, with each outer peg sharing one edge with the centre and one edge with each of its two outer neighbours. The solver must seat each nut on some peg, in some rotation, so that every pair of abutting edges carries the same number. There are exactly twelve abutting edges: six centre-to-outer pairs and six outer-to-outer pairs around the flower’s perimeter.
The puzzle was manufactured by Milton Bradley from under the trade name Drive Ya Nuts. The mechanical design is charmingly direct: the plastic nuts unscrew from the pegs, the problem is unmistakable, and a solver without computational aid is entirely alone with seven rotatable hexagons. Brute force works at configurations, but the constraint-programming encoding below reduces the search to a few dozen milliseconds.
The classical Milton Bradley piece set is shown in Figure 6.1. Edges are listed anti-clockwise from a canonical starting edge (labelled ); the canonical edge is always the one carrying the number unless two faces of the nut carry a , which does not occur in the instance.
The programming model
The tightest formulation treats each peg as a slot holding one (piece, rotation) pair, and derives six edge-colour variables per slot as the rotated copy of the chosen piece.
Variables
Let be the integer variable encoding which piece sits at slot , for (slot is the centre; slots through are the outer positions in anti-clockwise order starting from the top). Let encode the rotation of that piece, measured in steps. For each slot and each edge position (with the edge pointing towards the centre of the flower for outer slots, and the top edge for the centre slot), introduce an integer variable .
Piece-rotation-edge table
For each slot , enumerate the tuples that are consistent with the piece inventory (the -th edge of piece at rotation is ) and impose the table constraint.
Piece uniqueness
The seven pieces are distinct:
Edge-matching constraints
Six centre-to-outer matches: Six outer cyclic matches. Writing for the anti-clockwise neighbour of outer slot (with ):
A solver in fifty lines
from ortools.sat.python import cp_model
RINGS = [
[1, 6, 5, 4, 3, 2], # A
[1, 4, 3, 6, 5, 2], # B
[1, 6, 4, 2, 5, 3], # C
[1, 6, 2, 4, 5, 3], # D
[1, 6, 5, 3, 2, 4], # E
[1, 4, 6, 2, 3, 5], # F
[1, 2, 3, 4, 5, 6], # G
]
def solve():
m = cp_model.CpModel()
piece = [m.NewIntVar(0, 6, "") for _ in range(7)]
rot = [m.NewIntVar(0, 5, "") for _ in range(7)]
edge = [[m.NewIntVar(1, 6, "") for _ in range(6)]
for _ in range(7)]
tuples = []
for p in range(7):
for r in range(6):
row = [p, r]
for e in range(6):
row.append(RINGS[p][(e + r) % 6])
tuples.append(row)
for i in range(7):
m.AddAllowedAssignments(
[piece[i], rot[i]] + edge[i], tuples)
m.AddAllDifferent(piece)
# Centre to outer
for e in range(6):
m.Add(edge[0][e] == edge[e + 1][0])
# Outer cyclic
for i in range(1, 7):
j = i + 1 if i < 6 else 1
m.Add(edge[i][5] == edge[j][1])
s = cp_model.CpSolver()
s.Solve(m)
return [(s.Value(piece[i]),
s.Value(rot[i]),
[s.Value(edge[i][e]) for e in range(6)])
for i in range(7)]
The solver returns a seating assignment in roughly milliseconds. Enumerating all solutions returns exactly six, all rotations of one another: the centre piece is fixed and the outer ring is cyclically shifted. The solution is therefore unique up to the six-fold rotation (cyclic) symmetry of the flower, and is displayed in Figure 6.2: piece takes the centre, and pieces , , , , , occupy the six outer slots in anti-clockwise order starting from the top.
Sources. Drive Ya Nuts was introduced by Milton Bradley in and reissued intermittently thereafter; its seven-hexagon format is the best-known instance of the broader Japanese edge-matching puzzle family, which also includes Thompson’s MacMahon Hexagons and the Eternity II variant. The puzzle’s solution is unique up to the six-fold rotation (cyclic) symmetry of the solved flower; the solver finds exactly these six rotations and no others. The six reflections of the dihedral group are not physically realisable here, since flipping the flower over would require mirror-image nuts, which the inventory does not contain. The constraint-programming treatment given here is a straightforward edge-matching encoding; identical formulations scale unchanged to -hexagon or -hexagon flowers, at which point the search space grows past brute force but remains easy for modern CP solvers.