Chapter 173
Picture Frames That Crash To The Floor
Riddler Express
Imagine a framed picture suspended by a cord that hangs on two nails. If the picture were hung normally, you would expect the removal of one nail to leave it hanging on the other. How can you hang a picture on two nails so that if you remove either nail the picture crashes to the floor?
The Riddler, FiveThirtyEight, February 9, 2018(original post)
Solution
The idea. Each time the cord passes a nail, record an if it goes clockwise around nail and if counter-clockwise. Reading along the cord from one end to the other produces a word in the symbols . The picture stays up on a given subset of the nails present if and only if that word is the empty word in the free group generated by , i.e. once you erase every for and cancel adjacent inverses, nothing should remain.
So the Express asks: find a word in such that in the free group on (so the picture stays up when both nails are present), but once either generator is set equal to the identity.
The construction. The commutator does the job. Erase and the word becomes , which cancels to the empty word, so removing nail drops the picture. Erase and the word becomes , which again cancels. And is not the identity in the free group on (it is the standard generator of the commutator subgroup), so with both nails in place the cord cannot be pulled free.
The computation
Treat a hanging recipe as a list of pairs read along the cord. Free-group reduction is just a stack: walk the word, push each letter, and pop whenever the top two are mutual inverses. The picture stays up on subset iff the reduced word over is empty. Check that the commutator reduces to nothing when either generator is removed and survives reduction when both are present.
Implement free-group reduction as a one-pass stack.
Apply it to restricted to the surviving generator set.
Check on and on and .
def reduce(word):
stack = []
for g, s in word:
if stack and stack[-1] == (g, -s):
stack.pop()
else:
stack.append((g, s))
return stack
def restrict(word, keep):
return reduce([(g, s) for g, s in word if g in keep])
w = [(1, 1), (2, 1), (1, -1), (2, -1)] # x1 x2 x1^-1 x2^-1
print('both: ', restrict(w, {1, 2})) # nonempty
print('nail 1: ', restrict(w, {2})) # []
print('nail 2: ', restrict(w, {1})) # []
The script prints the full word for the “both” case (nontrivial), and [] for both single-nail restrictions: the picture is hanging when both nails are present and falls when either is removed.
Riddler Classic
What about three nails? What about four nails? What about on two red nails and two blue nails such that the picture falls if both red nails are removed and if both blue nails are removed but remains hanging if one of each colour is removed?
The Riddler, FiveThirtyEight, February 9, 2018(original post)
Solution
The pattern. Write for the commutator of two words. The Express used to enforce “both nails needed.” Iterating this construction yields a hanging recipe for any number of nails. The key fact: in the free group on , the commutator is trivial whenever either or is trivial, but is nontrivial whenever both and are nontrivial. So if is a hanging recipe for the first nails (falls when any one of them is removed, survives when all are present), then is a hanging recipe for nails.
Three nails. Start with the Express word , then form a word of length . Removing nail kills the two letters and leaves . Removing nail leaves , so the whole word reduces to . Same for nail . With all three nails in place, no further cancellation is possible and the word is nontrivial.
Four nails. The same idea, one step deeper. Setting in parallel and forming gives a balanced length- word. Removing any one of the four nails kills its bracketed factor (turning or into ), and the outer commutator then collapses to .
Two red, two blue. The red/blue puzzle wants the picture to fall iff both reds are removed or both blues are removed, but to stay up if one of each is removed. Let reds be nails and blues be nails . Form the commutator of the products a word of length . Removing both reds (kill and ): the first factor collapses to , and the commutator . Same with both blues. Removing one of each: say nails and are kept (so erased). The word becomes the Express commutator on the surviving generators, which is nontrivial. The four “one of each” cases all yield a -shaped commutator on the survivors.
The computation
Re-use the free-group reducer of The computation above. For each candidate word, take every subset of generators corresponding to a “nails present” state and reduce; verify the word is empty exactly when the puzzle says the picture should fall.
Build the four candidate words (three-nail iterated commutator, four-nail nested commutator, two-red-two-blue commutator).
For each, walk over all subsets of the nails.
Check the reduced restriction is empty iff the corresponding subset of nails is removed in the puzzle’s prescription.
def reduce(word):
stack = []
for g, s in word:
if stack and stack[-1] == (g, -s):
stack.pop()
else:
stack.append((g, s))
return stack
def restrict(word, keep):
return reduce([(g, s) for g, s in word if g in keep])
def inv(word):
return [(g, -s) for g, s in reversed(word)]
def commutator(a, b):
return a + b + inv(a) + inv(b)
x = {i: [(i, 1)] for i in (1, 2, 3, 4)}
# Three nails: [[x1, x2], x3]
w3 = commutator(commutator(x[1], x[2]), x[3])
print('3-nail length', len(w3))
for nails in [{1,2,3}, {2,3}, {1,3}, {1,2}]:
print(' keep', nails, '->', restrict(w3, nails))
# Four nails: [[x1, x2], [x3, x4]]
w4 = commutator(commutator(x[1], x[2]), commutator(x[3], x[4]))
print('4-nail length', len(w4))
for nails in [{1,2,3,4}, {2,3,4}, {1,3,4}, {1,2,4}, {1,2,3}]:
print(' keep', nails, '->', len(restrict(w4, nails)))
# Red/blue: [x1 x2, x3 x4], reds = {1,2}, blues = {3,4}
wrb = commutator(x[1] + x[2], x[3] + x[4])
print('red/blue length', len(wrb))
for nails in [{3,4}, {1,2}, {1,3}, {1,4}, {2,3}, {2,4}, {1,2,3,4}]:
print(' keep', nails, '->', restrict(wrb, nails))
The script prints, in summary: has length and reduces to the empty word when any one of nails is removed; has length and reduces to the empty word when any one of nails is removed; has length and reduces to the empty word when nails or are removed, but stays nontrivial for each of the four “one red, one blue” removals. All three cases match the boxed answer.