Help:=proc() print(` CurlNumR(L), CNCR(LR,N), ListRev(L) `): print(` CNC(L,N), CompactString(L,x,n), ListSubs(L,x,N) `): print(` RunningAvg(L), CNCfast(L,N) `): end: # Possible Questions to explore # Curling Number Conjecture: # # CNC: Does every starting sequence of pos. integers eventually hit a 1? # CNC-23: Does every starting sequence of 2's & 3's eventually hit a 1? # Gijswijt Sequence: # # Is there a tower lower bound (or upper bound) on the first time n appears? # Is the running average for the Gijswijt seq bounded? # Does the running average have a limit? # Does every 2-3 seq eventually become Gijswijt seq? # CurlNumR(L): inputs a list/seq L (in reverse order!), # and outputs the curling number for L CurlNumR:=proc(L) local n,i,m,k: n:=nops(L): m:=1: for i from 1 to n/2 do if [op(1..i,L)]=[op(i+1..2*i,L)] then for k from 3 while k*i<=n and [op(1..i,L)]=[op((k-1)*i+1..k*i,L)] do od: m:=max(m,k-1): fi: od: m: end: # CNCR(LR,N): inputs a list/seq LR (in reverse order!) # and a pos. int. N, and outputs the list (again in # reverse) with N more terms appended, where each # new term is the curling number of the sub-seq that # comes before it CNCR:=proc(LR,N) local i,c: option remember: if N=0 then RETURN(LR): fi: c:=CurlNumR(LR): CNCR([c,op(LR)],N-1): end: # ListRev(L): inputs a list L, and outputs # a list of L's elements in reverse order ListRev:=proc(L) local i: [seq(L[nops(L)-i], i=0..nops(L)-1)]: end: # CNC(L,N): inputs a starting list/seq L and # a pos. int. N, and outputs the list with # N more terms appended, where each new term # is the curling number of the string that # comes before it CNC:=proc(L,N) local LR,i,c: option remember: if N=0 then RETURN(L): fi: LR:=[seq(L[nops(L)-i], i=0..nops(L)-1)]: c:=CurlNumR(LR): CNC([op(L),c],N-1): end: # CNCfast(L,N): does the same thing as CNC # but is slightly faster by taking an iterative # (instead of a recursive) approach CNCfast:=proc(L,N) local LR,i,c: if N=0 then RETURN(L): fi: LR:=[seq(L[nops(L)-i], i=0..nops(L)-1)]: for i from 1 to N do c:=CurlNumR(LR): LR:=[c,op(LR)]: od: [seq(LR[nops(LR)-i], i=0..nops(LR)-1)]: end: # CompactString(L,x,n): inputs a list L, symbolic # variable x, and pos. int. n, and outputs a # "compact" version of L as follows: # # If i is the index where n first appears in L, # and Ln is the substring of L from 1 to i, # then the output would be L but with substrings # Ln replaced by x[n]. CompactString:=proc(L,x,n) local i,LC,j1,j2,A: if not member(n,L) then RETURN(L): fi: j1:=1: for j2 from 1 while L[j2]<>n do od: A:=[op(j1..j2,L)]: # Compact L LC:=[x[n]]: i:=j2+1: while i<=nops(L)-nops(A)+1 do if [op(i..i+nops(A)-1,L)]=A then LC:=[op(LC), x[n]]: i:=i+nops(A): else LC:=[op(LC), L[i]]: i:=i+1: fi: od: LC:=[op(LC), op(i..nops(L),L)]: [LC,{x[n]=A}]: end: # ListSubs(L,x,N): inputs list/seq L, symbolic variable x, # and pos. int. N, and outputs the "compact" version of # L (as described in CompactString) with "compactification" # using x[2],x[3],..x[N] ListSubs:=proc(L,x,N) local i,LC,S,L1: LC:=L: S:={}: for i from 2 to N do L1:=CompactString(LC,x,i): LC:=L1[1]: S:=S union L1[2]: od: [LC,S]: end: # RunningAvg(L): inputs a list L, and outputs a list of # the running average for entries in L RunningAvg:=proc(L) local M,n,Lsum: Lsum:=[]: M:=0: for n from 1 to nops(L) do M:=M+L[n]: Lsum:=[op(Lsum), evalf(M/n)]: od: Lsum: end: