###################################################################### ##RubikClock: Save this file as RubikClock. To use it, stay in the # ##same directory, get into Maple (by typing: maple ) # ##and then type: "read RubikClock: " (without the quotes) # ##Then follow the instructions given there # ## # ##Written by Doron Zeilberger, Temple University , # #zeilberg@math.temple.edu. # ####################################################################### #Created: Feb. 1, 1998 #This version: Feb. 1 1998 #RubikClock: A Maple package to solve Rubik's Clock #Please report bugs to zeilberg@math.temple.edu print(`Created Feb. 1, 1998.`): print(`This version: Feb. 1, 1998 `): lprint(``): print(`Written by Doron Zeilberger, zeilberg@math.temple.edu`): lprint(``): print(`Please report bugs to zeilberg@math.temple.edu`): lprint(``): print(`The most current version of this package and paper`): print(` are available from`): print(`http://www.math.temple.edu/~zeilberg`): print(`For a list of the procedures type ezra(), for help with`): print(`a specific procedure, type ezra(procedure_name)`): print(``): print(`If you want to restore a clock type Fix();`): ezra:=proc() if args=NULL then print(`This Maple program solves Rubik's clock puzzle.`): print(`Contains the following procedures: Fix, Restore`): fi: if nops([args])=1 and op(1,[args])=`Fix` then print(`Fix(): prompts for the positions of the clocks`): print(`and outputs instructions how to restore all the clocks`): print(`to 12 O'clock`): fi: if nops([args])=1 and op(1,[args])=`Restore` then print(`Restore(vect,u,d): given a vector of length 18 indicating the`): print(`current time on each of the 18 clocks, finds the`): print(`vector that restores it.`): print(`The 18 components of the first argument are the current`): print(`clock-readings of the dark-blue face, read in English`): print(`followed by the light-blue face, read in English`): print(`the 2nd and 3rd arguments are strings denoting Up and Down`): print(`respectively.`): print(`The output is a set of lists. each list has 6 components`): print(`The first component indicates which dial to rotate:`): print(` 1,2,3,4 read in English (with dark-side facing up)`): print(`followed by the settings of the buttons, read in English`): print(`followed by the ammount to rotate`): print(`Syntax is: Restore(vect,u,d):`): fi: end: # print(`The convention is that when the dark side is facing up`): # print(`a button is up is denoted by u, and a button is down is`): # print(`denoted by d. We first construct the 16 possible vectors`): # print(`A[j,d,d,d,d] ...., A[j,u,u,u,u], each of them of dimension 18`): # print(` where the dark clocks are numbered 1..9, like in English`): # print(`and the light clocks are numbered 10..18, like in English`): # print(`The i^{th} component of a given vector describes the effect`): # print(`of rotating the j^th dial (j=1,2,3,4), lisetd like in English`): # print(`from the dark side on the i^{th} clock`): #Restore(vect,u,d): given a vector of length 18 indicating the #current time on each of the 18 clocks, finds the #vector that restores is Restore:=proc(vect,u,d) local lu1,lu2,i,lam,eq,var,Vect,j,ku,mu,lu,A,Gu,mu1,vec,Mu: #begin uu A[1,u,u,u,u]:=[1,1,1,1,1,1,1,1,1,-1,0,-1,0,0,0,-1,0,-1]: A[1,u,u,u,d]:=[1,1,1,1,1,1,1,1,0,-1, 0,-1, 0, 0, 0, 0, 0,-1]: A[4,u,u,u,d]:=[0,0,0,0,0,0,0,0,1, 0, 0, 0,-1,-1, 0,-1,-1, 0]: A[1,u,u,d,u]:=[1,1,1,1,1,1,0,1,1,-1, 0,-1, 0, 0, 0,-1, 0, 0]: A[3,u,u,d,u]:=[0,0,0,0,0,0,1,0,0, 0, 0, 0, 0,-1,-1, 0,-1,-1]: A[1,u,u,d,d]:=[1,1,1,1,1,1,0,0,0,-1, 0,-1, 0, 0, 0, 0, 0, 0]: A[3,u,u,d,d]:=[0,0,0,0,0,0,1,0,1, 0, 0, 0, -1,-1,-1,-1,-1,-1]: ##end of uu #begin ud A[1,u,d,u,u]:=[1,1,0,1,1,1,1,1,1, 0, 0,-1, 0, 0, 0,-1, 0,-1]: A[2,u,d,u,u]:=[0,0,1,0,0,0,0,0,0,-1,-1, 0,-1,-1, 0, 0, 0, 0]: A[1,u,d,u,d]:=[1,1,0,1,1,0,1,1,0, 0, 0,-1, 0, 0, 0, 0, 0,-1]: A[2,u,d,u,d]:=[0,0,1,0,0,0,0,0,1,-1,-1, 0,-1,-1, 0,-1,-1, 0]: A[1,u,d,d,u]:=[1,1,0,1,1,1,0,1,1, 0, 0,-1, 0, 0, 0,-1, 0, 0]: A[2,u,d,d,u]:=[0,0,1,0,0,0,1,0,0,-1,-1, 0,-1,-1,-1, 0,-1,-1]: A[1,u,d,d,d]:=[1,1,0,1,1,0,0,0,0, 0, 0,-1, 0, 0, 0, 0, 0, 0]: A[2,u,d,d,d]:=[0,0,1,0,0,0,1,0,1,-1,-1, 0,-1,-1,-1,-1,-1,-1]: ##end of ud #begin du A[1,d,u,u,u]:=[1,0,0,0,0,0,0,0,0, 0,-1,-1, 0,-1,-1, 0, 0, 0]: A[2,d,u,u,u]:=[0,1,1,1,1,1,1,1,1,-1, 0, 0, 0, 0, 0,-1, 0,-1]: A[1,d,u,u,d]:=[1,0,0,0,0,0,0,0,1, 0,-1,-1,-1,-1,-1,-1,-1, 0]: A[2,d,u,u,d]:=[0,1,1,1,1,1,1,1,0,-1, 0, 0, 0, 0, 0, 0, 0,-1]: A[1,d,u,d,u]:=[1,0,0,0,0,0,1,0,0, 0,-1,-1, 0,-1,-1, 0,-1,-1]: A[2,d,u,d,u]:=[0,1,1,0,1,1,0,1,1,-1, 0, 0, 0, 0, 0,-1, 0, 0]: A[1,d,u,d,d]:=[1,0,0,0,0,0,1,0,1, 0,-1,-1,-1,-1,-1,-1,-1,-1]: A[2,d,u,d,d]:=[0,1,1,0,1,1,0,0,0,-1, 0, 0, 0, 0, 0, 0, 0, 0]: ##end of du #begin dd A[1,d,d,u,u]:=[1,0,1,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1, 0, 0, 0]: A[3,d,d,u,u]:=[0,0,0,1,1,1,1,1,1, 0, 0, 0, 0, 0, 0,-1, 0,-1]: A[1,d,d,u,d]:=[1,0,1,0,0,0,0,0,1,-1,-1,-1,-1,-1,-1,-1,-1, 0]: A[3,d,d,u,d]:=[0,0,0,1,1,0,1,1,0, 0, 0, 0, 0, 0, 0, 0, 0,-1]: A[1,d,d,d,u]:=[1,0,1,0,0,0,1,0,0,-1,-1,-1,-1,-1,-1, 0,-1,-1]: A[4,d,d,d,u]:=[0,0,0,0,1,1,0,1,1, 0, 0, 0, 0, 0, 0,-1, 0, 0]: A[1,d,d,d,d]:=[1,0,1,0,0,0,1,0,1,-1,-1,-1,-1,-1,-1,-1,-1,-1]: ##end of dd mu:= { [1,u,u,u,u], [1,u,u,u,d], [4,u,u,u,d], [1,u,u,d,u], [3,u,u,d,u], [1,u,u,d,d], [3,u,u,d,d], [1,u,u,u,u], [1,u,u,u,d], [4,u,u,u,d], [1,u,u,d,u], [3,u,u,d,u], [1,u,u,d,d], [3,u,u,d,d], [1,d,u,u,u], [2,d,u,u,u], [1,d,u,u,d], [2,d,u,u,d], [1,d,u,d,u], [2,d,u,d,u], [1,d,u,d,d], [2,d,u,d,d], [1,d,d,u,u], [3,d,d,u,u], [1,d,d,u,d], [3,d,d,u,d], [1,d,d,d,u], [4,d,d,d,u], [1,d,d,d,d] }: Gu:={}: mu1:={}: for i from 1 to nops(mu) do vec:=op(i,mu): if not member(A[op(vec)],Gu) then Gu:=Gu union {A[op(vec)]}: mu1:=mu1 union {vec}: fi: od: if nops(vect)<>18 then ERROR(`Input should have 18 components`): fi: for j from 1 to 18 do Vect[j]:=0: od: var:={}: for i from 1 to nops(mu1) do var:=var union {lam[op(op(i,mu1))]}: for j from 1 to 18 do Vect[j]:=Vect[j]-lam[op(op(i,mu1))]*A[op(op(i,mu1))][j]: od: od: eq:={}: for j from 1 to 18 do eq:=eq union {Vect[j]=vect[j]}: od: ku:=msolve(eq,12): if ku=NULL then ERROR(`No solutions`): fi: lu:={}: for i from 1 to nops(ku) do if op(2,op(i,ku))=op(1,op(i,ku)) then lu:=lu union {op(2,op(i,ku))}: fi: if type(op(2,op(i,ku)),string) then lu:=lu union {op(2,op(i,ku))}: fi: if op(2,op(i,ku))=0 then lu:=lu union {op(1,op(i,ku))}: fi: od: for i from 1 to nops(lu) do ku:=subs(op(i,lu)=0,ku): od: ku:=ku minus {0=0}: mu:=ku: for i from 1 to nops(ku) do if op(2,op(i,ku))=0 then mu:=mu minus {op(i,ku)}: fi: od: Mu:={}: for i from 1 to nops(mu) do lu:=op(i,mu): lu1:=op(1,lu): lu2:=op(2,lu): Mu:=Mu union {[op(1..nops(lu1),lu1),lu2]}: od: Mu: end: getvec:=proc() local v,a: v:=[]: print(`Welcome to RubikClock, a Maple program written by`): print(`Doron Zeilberger to solve Rubik's clock`): print(`Turn Rubik's clock with the dark-blue face up (the face`): print(`that has the logo matchbox on it)`): a:=readstat(`Type the time on the top-left clock, followed by a ; `): if not type(a,integer) or not (a>=0 and a<=12) then ERROR(`It should be an integer between 1 and 12 (inclusive)`): fi: v:=[op(v),a]: a:=readstat(`Type the time on the top-middle clock, followed by ;`): if not type(a,integer) or not (a>=0 and a<=12) then ERROR(`It should be an integer between 1 and 12 (inclusive)`): fi: v:=[op(v),a]: a:=readstat(`Type the time on the top-right clock, followed by ;`): if not type(a,integer) or not (a>=0 and a<=12) then ERROR(`It should be an integer between 1 and 12 (inclusive)`): fi: v:=[op(v),a]: a:=readstat(`Type the time on the middle-left clock, followed by ;`): if not type(a,integer) or not (a>=0 and a<=12) then ERROR(`It should be an integer between 1 and 12 (inclusive)`): fi: v:=[op(v),a]: a:=readstat(`Type the time on the middle-middle clock, followed by ;`): if not type(a,integer) or not (a>=0 and a<=12) then ERROR(`It should be an integer between 1 and 12 (inclusive)`): fi: v:=[op(v),a]: a:=readstat(`Type the time on the middle-right clock, followed by ;`): if not type(a,integer) or not (a>=0 and a<=12) then ERROR(`It should be an integer between 1 and 12 (inclusive)`): fi: v:=[op(v),a]: a:=readstat(`Type the time on the bottom-left clock, followed by ;`): if not type(a,integer) or not (a>=0 and a<=12) then ERROR(`It should be an integer between 1 and 12 (inclusive)`): fi: v:=[op(v),a]: a:=readstat(`Type the time on the bottom-middle clock, followed by ;`): if not type(a,integer) or not (a>=0 and a<=12) then ERROR(`It should be an integer between 1 and 12 (inclusive)`): fi: v:=[op(v),a]: a:=readstat(`Type the time on the bottom-right clock, followed by ;`): if not type(a,integer) or not (a>=0 and a<=12) then ERROR(`It should be an integer between 1 and 12 (inclusive)`): fi: v:=[op(v),a]: print(`Now, turn Rubik's clock over with the light-blue face up (the face`): print(`that has Arno Rubik's signature on it`): a:=readstat(`Type the time on the top-left clock, followed by a ; `): if not type(a,integer) or not (a>=0 and a<=12) then ERROR(`It should be an integer between 1 and 12 (inclusive)`): fi: v:=[op(v),a]: a:=readstat(`Type the time on the top-middle clock, followed by ;`): if not type(a,integer) or not (a>=0 and a<=12) then ERROR(`It should be an integer between 1 and 12 (inclusive)`): fi: v:=[op(v),a]: a:=readstat(`Type the time on the top-right clock, followed by ;`): if not type(a,integer) or not (a>=0 and a<=12) then ERROR(`It should be an integer between 1 and 12 (inclusive)`): fi: v:=[op(v),a]: a:=readstat(`Type the time on the middle-left clock, followed by ;`): if not type(a,integer) or not (a>=0 and a<=12) then ERROR(`It should be an integer between 1 and 12 (inclusive)`): fi: v:=[op(v),a]: a:=readstat(`Type the time on the middle-middle clock, followed by ;`): if not type(a,integer) or not (a>=0 and a<=12) then ERROR(`It should be an integer between 1 and 12 (inclusive)`): fi: v:=[op(v),a]: a:=readstat(`Type the time on the middle-right clock, followed by ;`): if not type(a,integer) or not (a>=0 and a<=12) then ERROR(`It should be an integer between 1 and 12 (inclusive)`): fi: v:=[op(v),a]: a:=readstat(`Type the time on the bottom-left clock, followed by ;`): if not type(a,integer) or not (a>=0 and a<=12) then ERROR(`It should be an integer between 1 and 12 (inclusive)`): fi: v:=[op(v),a]: a:=readstat(`Type the time on the bottom-middle clock, followed by ;`): if not type(a,integer) or not (a>=0 and a<=12) then ERROR(`It should be an integer between 1 and 12 (inclusive)`): fi: v:=[op(v),a]: a:=readstat(`Type the time on the bottom-right clock, followed by ;`): if not type(a,integer) or not (a>=0 and a<=12) then ERROR(`It should be an integer between 1 and 12 (inclusive)`): fi: v:=[op(v),a]: v: end: targem:=proc(vec,u): if not type(vec,list) or nops(vec)<>6 then ERROR(`Bad input`): fi: if op(2,vec)=u then print(`Push the top-left button UP`): else print(`Push the top-left button DOWN`): fi: if op(3,vec)=u then print(`Push the top-right button UP`): else print(`Push the top-right button DOWN`): fi: if op(4,vec)=u then print(`Push the bottom-left button UP`): else print(`Push the bottom-left button DOWN`): fi: if op(5 ,vec)=u then print(`Push the bottom-right button UP`): else print(`Push the bottom-right button DOWN`): fi: if op(1,vec)=1 then if op(6,vec)<=6 then print(`Turn the top-left dial`, op(6,vec),` hours forward`): else print(`Turn the top-left dial`, 12-op(6,vec),` hours backward`): fi: fi: if op(1,vec)=2 then if op(6,vec)<=6 then print(`Turn the top-right dial`, op(6,vec),` hours forward`): else print(`Turn the top-right dial`, 12-op(6,vec),` hours backward`): fi: fi: if op(1,vec)=3 then if op(6,vec)<=6 then print(`Turn the bottom-left dial`, op(6,vec),` hours forward`): else print(`Turn the bottom-left dial`, 12-op(6,vec),` hours backward`): fi: fi: if op(1,vec)=4 then if op(6,vec)<=6 then print(`Turn the bottom-right dial`, op(6,vec), `hours forward`): else print(`Turn the bottom-right dial`, 12-op(6,vec), `hours backward`): fi: fi: end: Fix:=proc() local i,v,gu,u,d: v:=getvec(); gu:=Restore(v,u,d): if gu={} then print(`There is nothing to do`): else print(`Place your clock with the dark-blue side up(the one the matchbox`): print(`logo on it` ): print(`Follow the following steps`): for i from 1 to nops(gu) do lprint(`STEP`, i): targem(op(i,gu),u): od: fi: print(`If you followed the instructions correctly, then`): print(`the clocks should be all restored`): end: