#OK to post #Yuxuan Yang, Jan 31st, Assignment 3 Help:=proc(): print(`NewUCG(n),checkNewUCG(n),Tomorrow(DATE),Yesterday(DATE),MyNEXG(w)`): end: with(combinat): #NewUCG(n): has the same input and output as UCG(n), but instead starts with the vector [0$n] and keeps applying NEXG(w), always appending the new guy to the list. Check that UCG(n)=NewUCG(n) are the same for n from 1 to 14. NewUCG:=proc(n) local i,m,B: m:=2^n-1: B:=[[0$n]]: for i from 1 to m do B:=[op(B),NEXG(B[i])]: od: B: end: #checkNewUCG: Check that UCG(n)=NewUCG(n) are the same for n from 1 to 14.(run it for n=14) checkNewUCG:=proc(n) local i: for i from 1 to n do if not UCG(i)=NewUCG(i) then RETURN(FAIL): fi: od: print(`nice`): end: #UCG(n): inputs a non-neg. integer n, and outputs the n-dim unit cube [0,1]^n #USING THE GRAY-CODE WHERE ONLY ONE BIT CHANGES AT A TIME #AS A LIST OF 0-1 vectors in Lex-order (same as Box([1$n]) UCG:=proc(n) local B: option remember: if n=0 then RETURN([[]]): fi: B:=UCG(n-1): CAT(PreP(0,B),PreP(1,REV(B))): end: #BoxG(L):inputs a list of positive integers and outputs a list whose members are the same as Box(L), but in such an order that when you go from one member to the next, it only changes in one place BoxG:=proc(L) local i,B1,L1,k,B,o: option remember: k:=nops(L): if k=0 then RETURN([[]]): fi: L1:=[op(1..k-1,L)]: B1:=BoxG(L1): B:=[]: o:=0: for i from 0 to L[k] do if o=0 then B:=CAT(B,App(B1,i)): o:=1: else B:=CAT(B,App(REV(B1),i)): o:=0: fi: od: B: end: #results of BoxG([2, 2, 2]); # [[0, 0, 0], [1, 0, 0], [2, 0, 0], [2, 1, 0], [1, 1, 0], # [0, 1, 0], [0, 2, 0], [1, 2, 0], [2, 2, 0], [2, 2, 1], # [1, 2, 1], [0, 2, 1], [0, 1, 1], [1, 1, 1], [2, 1, 1], # [2, 0, 1], [1, 0, 1], [0, 0, 1], [0, 0, 2], [1, 0, 2], # [2, 0, 2], [2, 1, 2], [1, 1, 2], [0, 1, 2], [0, 2, 2], # [1, 2, 2], [2, 2, 2]] Tomorrow:=proc(Date) local Date1,isleapyear,ly,ny: Date1:=Date: if Date[4]=7 then Date1[4]:=1: else Date1[4]:=Date[4]+1: fi: if Date[3] mod 400=0 then isleapyear:=true: elif Date[3] mod 100=0 then isleapyear:=false: elif Date[3] mod 4=0 then isleapyear:=true: else isleapyear:=false: fi: ly:=[31,29,31,30,31,30,31,31,30,31,30,31]: ny:=[31,28,31,30,31,30,31,31,30,31,30,31]: if isleapyear then if Date[1]=ly[Date[2]] then Date1[1]:=1: if Date[2]=12 then Date1[2]:=1: Date1[3]:=Date[3]+1: else Date1[2]:=Date[2]+1: fi: else Date1[1]:=Date[1]+1: fi: else if Date[1]=ny[Date[2]] then Date1[1]:=1: if Date[2]=12 then Date1[2]:=1: Date1[3]:=Date[3]+1: else Date1[2]:=Date[2]+1: fi: else Date1[1]:=Date[1]+1: fi: fi: Date1: end: Yesterday:=proc(Date) local i,j,k,l,Date1: for i from 1 to 31 do for j from 1 to 12 do for k from Date[3]-1 to Date[3] do for l from 1 to 7 do if Tomorrow([i,j,k,l])=Date then RETURN([i,j,k,l]): fi: od: od: od: od: end: #MyNEXG(w): Using the idea about Gray code on Chapter 1 of the Nijenhuis-Wilf masterpiece MyNEXG:=proc(w) local n,s,i,w1,j: n:=nops(w): if w=[1,0$(n-1)] then print(w, `is the last one`): RETURN(FAIL): fi: w1:=w: s:=add(w[i],i=1..n): if s mod 2=0 then w1[n]:= (w[n]+1) mod 2: else for i from 1 to n-1 do j:=n+1-i: if w[j]=1 then w1[j-1]:=(w[j-1]+1) mod 2: RETURN(w1): fi: od: fi: w1: end: ##codes from C3 Help3:=proc():print(` Box(L), CAT(L1,L2) , PreP(a,L), App(L,a), UC(n) , NEX(w) `): print(`REV(L), UCG(n), NEXG(w), PREG(w) , RBW(n)`): end: #Box(L): Inputs a list L (where k=nops(L)) of non-negative integers L outputs #the LIST of all LISTS [a1,a2,..., ak] in LEX ORDER such that ai is in {0,1,.., L[i]) #In particular the n-dim UNIT cube would be Box([1$n]); Box:=proc(L) local k,i,L1,B1,j: option remember: if not type(L,list) then print(L, `should be a list `): RETURN(FAIL): fi: k:=nops(L): if k=0 then RETURN([[]]): fi: if not ({seq(type(L[i],integer),i=1..nops(L))}={true} and min(op(L))>=0) then print(`bad input`): RETURN(FAIL): fi: L1:=[op(1..k-1,L)]: B1:=Box(L1): [ seq(seq([op(B1[j]),i],i=0..L[k]),j=1.. nops(B1))]: end: #CAT(L1,L2): joining two lists in order CAT:=proc(L1,L2): [op(L1),op(L2)]:end: #PreP(a,L): Given a list L of lists, outputs the list where #sticks a to the beginnin of each of them #For example #PreP(0,[[1,2,3],[1,3,4]])= [[0,1,2,3],[0,1,3,4]] PreP:=proc(a,L) local i: [ seq([a, op(L[i])],i=1..nops(L))]:end: #App(L,a): Given a list L of lists, outputs the list where #sticks a to the end of each of them #For example #App([[1,2,3],[1,3,4]],0)= [[1,2,3,0],[1,3,4,0]] App:=proc(L,a) local i: [ seq([op(L[i]),a],i=1..nops(L))]:end: #UC(n): inputs a non-neg. integer n, and outputs the n-dim unit cube [0,1]^n #AS A LIST OF 0-1 vectors in Lex-order (same as Box([1$n]) UC:=proc(n) local B: option remember: if n=0 then RETURN([[]]): fi: B:=UC(n-1): CAT(PreP(0,B),PreP(1,B)): end: #NEX(w): Inputs a 0-1 vector w (of length n=nops(w)) outputs the vector right after it in lex order #or returns FAIL NEX:=proc(w) local n,w1: n:=nops(w): if n=0 then print(`You have reached the top`): RETURN(FAIL): fi: w1:=[op(1..n-1,w)]: if w[n]=0 then RETURN([op(w1),1]): fi: w1:=NEX(w1): if w1=FAIL then RETURN(FAIL): else RETURN([op(w1),0]): fi: end: #NEXr(w): Inputs a 0-1 vector w (of length n=nops(w)) outputs the vector right after it in lex order #or returns FAIL NEXr:=proc(w) local n,w1: option remember: n:=nops(w): if n=0 then print(`You have reached the top`): RETURN(FAIL): fi: w1:=[op(1..n-1,w)]: if w[n]=0 then RETURN([op(w1),1]): fi: w1:=NEXr(w1): if w1=FAIL then RETURN(FAIL): else RETURN([op(w1),0]): fi: end: #REV(L): REV:=proc(L) local i: [seq(L[-i],i=1..nops(L))]:end: #UCG(n): inputs a non-neg. integer n, and outputs the n-dim unit cube [0,1]^n #USING THE GRAY-CODE WHERE ONLY ONE BIT CHANGES AT A TIME #AS A LIST OF 0-1 vectors in Lex-order (same as Box([1$n]) UCG:=proc(n) local B: option remember: if n=0 then RETURN([[]]): fi: B:=UCG(n-1): CAT(PreP(0,B),PreP(1,REV(B))): end: #NEXG(w): inputs a word in {0,1}^n (n=nops(w)) and outputs the NEXT one in the the Gray Code given by UCG(n). #Try: NEXG([1,0,1]); NEXG:=proc(w) local n,w1, w1Next,w1Prev: n:=nops(w): if n=1 then if w[1]=0 then RETURN([1]): else RETURN(FAIL): fi: fi: w1:=[op(2..n,w)]: if w[1]=0 then w1Next:=NEXG(w1): if w1Next=FAIL then RETURN([1,op(w1)]): else RETURN([0,op(w1Next)]): fi: elif w[1]=1 then #Since w[1]=1, we are going BACKWARDS w1Prev:=PREG(w1): if w1Prev=FAIL then #IF THERE IS NO WAY TO GO WE RETURN FAIL RETURN(FAIL): else RETURN([1,op(w1Prev)]): fi: else print(`Something is wrong`): RETURN(FAIL): fi: end: #PREG(w): inputs a word in {0,1}^n (n=nops(w)) and outputs the PREVIOUS one in the the Gray Code given by UCG(n). #Try: NEXG([1,0,1]); PREG:=proc(w) local n,w1, w1Prev,w1Next: n:=nops(w): if n=1 then if w[1]=0 then RETURN(FAIL): else RETURN([0]): fi: fi: w1:=[op(2..n,w)]: if w[1]=0 then w1Prev:=PREG(w1): if w1Prev=FAIL then RETURN(FAIL): else RETURN([0,op(w1Prev)]): fi: elif w[1]=1 then #Since w[1]=1, we are going FORWARD w1Next:=NEXG(w1): if w1Next=FAIL then #WE CHANGE THE first bit RETURN([0,op(w1)]): else RETURN([1,op(w1Next)]): fi: else print(`Something is wrong`): RETURN(FAIL): fi: end: #RBW(n): A random binary word in {0,1} of length n RBW:=proc(n) local ra,i: ra:=rand(0..1): [seq(ra(),i=1..n)]: end: ##end of C3