Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
52 views

Light Puzzle

This puzzle is taken from a lab assignment given to UCSD undergraduates in their linear algebra course. (It can be found here.)

In a kingdom far, far away, the King decided that the time had come to find a husband for his princess daughter. The King wanted to find a worthy lad for his princess, so he promised to give his daughter away to the first young (or old) man who would solve the puzzle that had stumped the best of his court mathematicians for years. The puzzle was very simple: in a palace, there are 25 rooms arranged in a square---5 rows of rooms with 5 rooms in each row. In every room there is a light switch which not only switches on/off the light in that room, but also switches the lights in the adjacent rooms---the room to the right, to the left, the room above, and the room below. Initially, all of the lights are turned off. The goal is to turn the lights on in every room of the palace.

You can try out the puzzle below. The "Clear" button will allow you to clear all the lights and start over.

R1 R2 R3 R4 R5
R6 R7 R8 R9 R10
R11 R12 R13 R14 R15
R16 R17 R18 R19 R20
R21 R22 R23 R24 R25
 

Encode each switch as a vector of zeros and ones. A one in the iith position indicates that the switch will toggle the light in the iith room. For example, Switch 1 toggles the lights in Rooms 1, 2, and 6; therefore, the switch in Room 1 can be encoded as the following vector: v1=[1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]T. v_{1} = \left[ 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\right]^{T}.

The switch in Room 2 is v2=[1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]T. v_{2} = \left[ 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\right]^{T}.

What happens if we flip both switches in Room 1 and Room 2? This is accomplished by adding v1v_{1} and v2v_{2}. The trick, though, is to do all calculations mod 2. To see why this makes sense, consider Room 1: the vector v1v_{1} has a one in the first slot, so when we flip the switch in Room 1, the light in Room 1 turns on. Now we flip the switch in Room 2. The vector v2v_{2} also has a one in the first slot, so if we add v1+v2v_{1} + v_{2}, we get a two in the first slot. But the actual effect of the latter switch is to turn the light in Room 1 off again. So this two should be a zero.

Let's try this in Sage.

v1 = vector(Integers(2), [1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) # The Integers(2) argument ensures that this vector's entries are interpreted as mod 2 integers. show(v1)
(1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)\displaystyle \left(1,\,1,\,0,\,0,\,0,\,1,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0\right)
v2 = vector(Integers(2), [1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) show(v2)
(1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)\displaystyle \left(1,\,1,\,1,\,0,\,0,\,0,\,1,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0\right)
show(v1 + v2)
(0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)\displaystyle \left(0,\,0,\,1,\,0,\,0,\,1,\,1,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0,\,0\right)

Check that the above answer makes sense by going to the game board above and verifying that flipping the switches in Room 1 and Room 2 will result in having the lights on in Rooms 3, 6, and 7.

To solve the problem, we need to turn on a set of switches. Note that the order in which we flip the switches is irrelevant and we never need to flip any switch more than once. In other words, each switch will either be flipped or not.

Let vinitv_{init} be the initial state of the lights. (This is just the zero vector in our scenario.)

Now let ci=0c_{i} = 0 if we leave the switch in Room ii alone and ci=1c_{i} = 1 if we flip the switch in Room ii. Then the final state of the lights will be vinit+c1v1+c2v2++c25v25. v_{init} + c_{1}v_{1} + c_{2} v_{2} + \dots + c_{25} v_{25}.

Let vfinalv_{final} be the final state we want to achieve. (If the goal is to turn on all the lights, then vfinalv_{final} will be a vector of all ones.)

Therefore, solving our puzzle is equivalent to solving the equation vinit+c1v1+c2v2++c25v25=vfinal v_{init} + c_{1}v_{1} + c_{2} v_{2} + \dots + c_{25} v_{25} = v_{final} for the coefficients cic_{i}. Or put another way, if we let v=vfinalvinitv = v_{final} - v_{init}, then we need to solve c1v1+c2v2++c25v25=v. c_{1}v_{1} + c_{2} v_{2} + \dots + c_{25} v_{25} = v.

Recall that the above expression of a linear combination of vectors is equivalent to a system of linear equations, encoded in a matrix-vector equation as Vc=v Vc = v where VV is the matrix with columns viv_{i}, and cc is the vector of coefficients cic_{i}.

Let's set up the augmented matrix for this system. If you write out the 25 x 25 matrix VV, you'll see that it takes the block form [AIOOOIAIOOOIAIOOOIAIOOOIA] \begin{bmatrix} A & I & O & O & O \\ I & A & I & O & O \\ O & I & A & I & O \\ O & O & I & A & I \\ O & O & O & I & A \end{bmatrix} where AA is the 5x5 block [1100011100011100011100011], \begin{bmatrix} 1 & 1 & 0 & 0 & 0 \\ 1 & 1 & 1 & 0 & 0 \\ 0 & 1 & 1 & 1 & 0 \\ 0 & 0 & 1 & 1 & 1 \\ 0 & 0 & 0 & 1 & 1 \end{bmatrix}, II is the 5x5 identity matrix, and OO is the 5x5 zero matrix.

Let's define VV in Sage.

A = matrix(Integers(2), 5, 5, [[1, 1, 0, 0, 0], [1, 1, 1, 0, 0], [0, 1, 1, 1, 0], [0, 0, 1, 1, 1], [0, 0, 0, 1, 1]]) show(A) I = identity_matrix(Integers(2), 5) show(I) O = zero_matrix(Integers(2), 5) show(O)
(1100011100011100011100011)\displaystyle \left(\begin{array}{rrrrr} 1 & 1 & 0 & 0 & 0 \\ 1 & 1 & 1 & 0 & 0 \\ 0 & 1 & 1 & 1 & 0 \\ 0 & 0 & 1 & 1 & 1 \\ 0 & 0 & 0 & 1 & 1 \end{array}\right)
(1000001000001000001000001)\displaystyle \left(\begin{array}{rrrrr} 1 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 0 & 1 \end{array}\right)
(0000000000000000000000000)\displaystyle \left(\begin{array}{rrrrr} 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 \end{array}\right)
V = block_matrix(5, 5, [[A, I, O, O, O], [I, A, I, O, O], [O, I, A, I, O], [O, O, I, A, I], [O, O, O, I, A]]) show(V)
(1100010000000000000000000111000100000000000000000001110001000000000000000000011100010000000000000000000110000100000000000000010000110001000000000000000100011100010000000000000001000111000100000000000000010001110001000000000000000100011000010000000000000001000011000100000000000000010001110001000000000000000100011100010000000000000001000111000100000000000000010001100001000000000000000100001100010000000000000001000111000100000000000000010001110001000000000000000100011100010000000000000001000110000100000000000000010000110000000000000000000100011100000000000000000001000111000000000000000000010001110000000000000000000100011)\displaystyle \left(\begin{array}{rrrrr|rrrrr|rrrrr|rrrrr|rrrrr} 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 1 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ \hline 1 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ \hline 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\ \hline 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 0 & 0 & 0 & 0 & 1 \\ \hline 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 \end{array}\right)

Now we can form the augmented matrix with v=vfinalvinitv = v_{final} - v_{init} as the last column. Remember that vfinalv_{final} is a vector of all ones (all the lights need to be turned on) and vinitv_{init} is the zero vector (all the lights are off at the beginning).

# We could just do this: ## v = vector(Integers(2), [1] * 25) # to get a vector with 25 ones. # But I'm going to do something a little trickier so that the # augmented matrix will preserve the pretty block formatting. v = matrix(Integers(2), 25, 1, [1] * 25) # This is a column vector (25 x 1 matrix) of ones. v.subdivide([5, 10, 15, 20], None) # Then the subdivide method makes it a block matrix in groups of 5 V_aug = V.augment(v, subdivide = True) show(V_aug)
(11000100000000000000000001111000100000000000000000010111000100000000000000000100111000100000000000000001000110000100000000000000011000011000100000000000000101000111000100000000000001001000111000100000000000010001000111000100000000000100001000110000100000000001000001000011000100000000010000001000111000100000000100000001000111000100000001000000001000111000100000010000000001000110000100000100000000001000011000100001000000000001000111000100010000000000001000111000100100000000000001000111000101000000000000001000110000110000000000000001000011000100000000000000001000111001000000000000000001000111010000000000000000001000111100000000000000000001000111)\displaystyle \left(\begin{array}{rrrrr|rrrrr|rrrrr|rrrrr|rrrrr|r} 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 1 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 1 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ \hline 1 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ \hline 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 \\ \hline 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 0 & 0 & 0 & 0 & 1 & 1 \\ \hline 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 \end{array}\right)

Now we simply row reduce. The row reduction will automatically be done mod 2 because all the objects that form VaugV_{aug} were defined over the integers mod 2.

solution_matrix = V_aug.rref() show(solution_matrix)
(10000000000000000000000010010000000000000000000001010010000000000000000000011100010000000000000000000100000010000000000000000000110000010000000000000000011000000010000000000000000001000000010000000000000001110000000010000000000000000100000000010000000000000110000000000010000000000001000000000000010000000000010000000000000010000000000001000000000000010000000001010000000000000010000000010100000000000000010000000111000000000000000010000000010000000000000000010000011000000000000000000010000001000000000000000000010001110000000000000000000010001100000000000000000000010101000000000000000000000011100000000000000000000000000000000000000000000000000000)\displaystyle \left(\begin{array}{rrrrr|rrrrr|rrrrr|rrrrr|rrrrr|r} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 \\ 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 1 & 1 \\ 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 1 \\ \hline 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 1 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 1 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 1 & 0 \\ \hline 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 \\ \hline 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 1 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 1 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & 1 \\ \hline 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 1 & 1 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \end{array}\right)

Looking at the bottom of the above matrix, we can see two rows of zeros. That means that we have two free variables. One easy solution is to set the free variables equal to zero, and then the particular solution s1s_{1} is just the last column of the augmented matrix above. (The 26th column is actually indexed as 25 because the first column is indexed—as everything is in Python—by 0.)

s1 = solution_matrix.column(25) # This extracts the 26th column (the augmented column) from the row-reduced solution matrix. show(s1)
(0,1,1,0,1,0,1,1,1,0,0,0,1,1,1,1,1,0,1,1,1,1,0,0,0)\displaystyle \left(0,\,1,\,1,\,0,\,1,\,0,\,1,\,1,\,1,\,0,\,0,\,0,\,1,\,1,\,1,\,1,\,1,\,0,\,1,\,1,\,1,\,1,\,0,\,0,\,0\right)

To make this easier to read, let's arrange the vector s1s_{1} as a 5 x 5 array so you can tell which rooms correspond to the ones.

show(matrix(5, 5, [s1[5*i:5*i+5] for i in range(5)])) # This is just a fancy way of extracting the entries of s1 five at a time.
(0110101110001111101111000)\displaystyle \left(\begin{array}{rrrrr} 0 & 1 & 1 & 0 & 1 \\ 0 & 1 & 1 & 1 & 0 \\ 0 & 0 & 1 & 1 & 1 \\ 1 & 1 & 0 & 1 & 1 \\ 1 & 1 & 0 & 0 & 0 \end{array}\right)

Check that this is a solution by clearing the game board and flipping the switches according to the solution above (i.e., Rooms 2, 3, 5, 7, 8, 9, etc.) It might be useful to use the "Split view" button in the toolbar to be able to see the solution and the game board at the same time. (Hit it twice to get a vertical split instead of a horizontal split.)

The other solutions are obtained by adding the particular solution s1s_{1} to all vectors in the null space. These are typically obtained by taking the negative of the 24th and 25th columns of the reduced matrix, and including an extra 1 corresponding to the free variable (in the 24th or 25th slot). However, in arithmetic mod 2, -1 is the same as 1, so we don't need to worry about the negative signs.

x24 = solution_matrix.column(23) # Grab the 24th column x24[23] = 1 # Put an extra 1 in the 24th slot x25 = solution_matrix.column(24) # Grab the 25th column x25[24] = 1 # Put an extra 1 in the 25th slot show(x24) show(x25)
(0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0)\displaystyle \left(0,\,1,\,1,\,1,\,0,\,1,\,0,\,1,\,0,\,1,\,1,\,1,\,0,\,1,\,1,\,1,\,0,\,1,\,0,\,1,\,0,\,1,\,1,\,1,\,0\right)
(1,0,1,0,1,1,0,1,0,1,0,0,0,0,0,1,0,1,0,1,1,0,1,0,1)\displaystyle \left(1,\,0,\,1,\,0,\,1,\,1,\,0,\,1,\,0,\,1,\,0,\,0,\,0,\,0,\,0,\,1,\,0,\,1,\,0,\,1,\,1,\,0,\,1,\,0,\,1\right)

Of course, since we're only working with numbers mod 2, the only possible multiples are zero or one. If x24x_{24} and x25x_{25} are a basis for the null space, then all possible solutions are given by s1+ax24+bx25 s_{1} + ax_{24} + bx_{25} where aa and bb can only be zero or one.

We've already seen s1s_{1} (the result of setting aa and bb equal to zero). Here are the other possible solutions:

s2 = s1 + x24 show(matrix(5, 5, [s2[5*i:5*i+5] for i in range(5)])) s3 = s1 + x25 show(matrix(5, 5, [s3[5*i:5*i+5] for i in range(5)])) s4 = s1 + x24 + x25 show(matrix(5, 5, [s4[5*i:5*i+5] for i in range(5)]))
(0001111011111000111010110)\displaystyle \left(\begin{array}{rrrrr} 0 & 0 & 0 & 1 & 1 \\ 1 & 1 & 0 & 1 & 1 \\ 1 & 1 & 1 & 0 & 0 \\ 0 & 1 & 1 & 1 & 0 \\ 1 & 0 & 1 & 1 & 0 \end{array}\right)
(1100011011001110111001101)\displaystyle \left(\begin{array}{rrrrr} 1 & 1 & 0 & 0 & 0 \\ 1 & 1 & 0 & 1 & 1 \\ 0 & 0 & 1 & 1 & 1 \\ 0 & 1 & 1 & 1 & 0 \\ 0 & 1 & 1 & 0 & 1 \end{array}\right)
(1011001110111001101100011)\displaystyle \left(\begin{array}{rrrrr} 1 & 0 & 1 & 1 & 0 \\ 0 & 1 & 1 & 1 & 0 \\ 1 & 1 & 1 & 0 & 0 \\ 1 & 1 & 0 & 1 & 1 \\ 0 & 0 & 0 & 1 & 1 \end{array}\right)

What do you notice about these four solutions? Do these really represent four unique solutions to the puzzle?

The quick way

We can get to the answer quicker by using some handy linear algebra functionality built into Sage. Rather than row reducing and then extracting vectors from a matrix, let's allow Sage to simply solve the matrix-vector equation. (To make this work, though, we need to define vv as a vector, and not a 25 x 1 matrix.)

v = vector(Integers(2), [1] * 25) s1 = V\v show(matrix(5, 5, [s1[5*i:5*i+5] for i in range(5)]))
(0110101110001111101111000)\displaystyle \left(\begin{array}{rrrrr} 0 & 1 & 1 & 0 & 1 \\ 0 & 1 & 1 & 1 & 0 \\ 0 & 0 & 1 & 1 & 1 \\ 1 & 1 & 0 & 1 & 1 \\ 1 & 1 & 0 & 0 & 0 \end{array}\right)
V_nullspace = V.kernel() show(V_nullspace) x24 = V_nullspace[1] #Strangely, these entries are not zero-indexed. x25 = V_nullspace[2]
RowSpanZ/2Z(10101101010000010101101010111010101110111010101110)\displaystyle \mathrm{RowSpan}_{\ZZ/2\ZZ}\left(\begin{array}{rrrrrrrrrrrrrrrrrrrrrrrrr} 1 & 0 & 1 & 0 & 1 & 1 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 1 & 1 & 0 & 1 & 0 & 1 \\ 0 & 1 & 1 & 1 & 0 & 1 & 0 & 1 & 0 & 1 & 1 & 1 & 0 & 1 & 1 & 1 & 0 & 1 & 0 & 1 & 0 & 1 & 1 & 1 & 0 \end{array}\right)
s2 = s1 + x24 show(matrix(5, 5, [s2[5*i:5*i+5] for i in range(5)])) s3 = s1 + x25 show(matrix(5, 5, [s3[5*i:5*i+5] for i in range(5)])) s4 = s1 + x24 + x25 show(matrix(5, 5, [s4[5*i:5*i+5] for i in range(5)]))
(1100011011001110111001101)\displaystyle \left(\begin{array}{rrrrr} 1 & 1 & 0 & 0 & 0 \\ 1 & 1 & 0 & 1 & 1 \\ 0 & 0 & 1 & 1 & 1 \\ 0 & 1 & 1 & 1 & 0 \\ 0 & 1 & 1 & 0 & 1 \end{array}\right)
(0001111011111000111010110)\displaystyle \left(\begin{array}{rrrrr} 0 & 0 & 0 & 1 & 1 \\ 1 & 1 & 0 & 1 & 1 \\ 1 & 1 & 1 & 0 & 0 \\ 0 & 1 & 1 & 1 & 0 \\ 1 & 0 & 1 & 1 & 0 \end{array}\right)
(1011001110111001101100011)\displaystyle \left(\begin{array}{rrrrr} 1 & 0 & 1 & 1 & 0 \\ 0 & 1 & 1 & 1 & 0 \\ 1 & 1 & 1 & 0 & 0 \\ 1 & 1 & 0 & 1 & 1 \\ 0 & 0 & 0 & 1 & 1 \end{array}\right)