function parse( s ){ delete sl; delete sr while(length(s)>0){ if(match(s,/^[0-9]+/)){ num[++pindex] = substr(s,RSTART,RLENGTH) s = substr(s,RSTART+RLENGTH) continue } else if(s~/^\]/){ # ] l = sl[slp--] r = pindex # print "left",l,"right",r num[++pindex] = -1 ile[pindex] = l iri[pindex] = r if(slp==0) root = pindex } else if(s~/^,/){ # , sl[++slp] = pindex } s = substr(s,2) } } function cleanparse(s){ delete ile; delete iri; delete num; delete sl slp = 0 pindex = 0 parse(s) } function parent(id){ for(i in ile) if(ile[i]==id || iri[i]==id) return i return -1 } function levels(id){ i = id count = 0 if(id==root) return 0 do{ i = parent(i) if(i<0) return -1 count++ }while(i!=root) return count } function treetostring(id){ if(num[id]<0) return "[" treetostring(ile[id]) "," treetostring(iri[id]) "]" else return num[id] } function leftitemi(id){ do{ id-- }while((num[id]<0 && id>0)) return id } function rightitemi(id){ do{ id++ }while((num[id]<0 && id<=length(num))) return id } function explode(id){ lefti = leftitemi(id) if(lefti>0){ num[lefti] += num[id] num[id]=-1 } righti = rightitemi(id) rightrighti = rightitemi(righti) if(rightrighti<=length(num)){ num[rightrighti] += num[righti] num[righti] = -1 } p = parent(id) num[p] = 0 } function toexplode(){ for(id=1;id<=pindex;id++){ if((num[id]>=0) && (levels(id)>4) && num[parent(id)]<0) return id } return -1 } function dosplit(id){ n = num[id] nl = int(n/2) nr = int(n/2) + n%2 num[id] = -1 num[++pindex] = nl ile[id] = pindex num[++pindex] = nr iri[id] = pindex } function tosplit(){ for(id=1;id<=pindex;id++){ # print id, (num[id]-10>0), num[id] if((num[id]-10>=0) && num[parent(id)]<0 ) return id } return -1 } function reduce(){ do{ ind = toexplode() print "explode?", ind, num[ind], parent(ind), num[parent(ind)],num[leftitemi(ind)] if(ind>0){ explode(ind) print "exploded", treetostring(root) s = treetostring(root) cleanparse(s) # print "to split?",tosplit() continue } ind = tosplit() print "split?", ind, num[ind], parent(ind), num[parent(ind)], ile[parent(ind)], iri[parent(ind)] if(ind>0){ dosplit(ind) print "split", treetostring(root) s = treetostring(root) cleanparse(s) } print toexplode(), tosplit() } while( ((toexplode()>0) || (tosplit()>0)) ) print "done" } function magnitude(id){ if(num[id]>=0) return num[id] # regular number # node return magnitude(ile[id])*3 + magnitude(iri[id])*2 } BEGIN{ pindex = 0 } NR==1{ parse($0) proot = root } NR>1{ parse( $0 ) num[++pindex] = -1 ile[pindex] = proot iri[pindex] = root root = pindex print "raw add",NR, treetostring(root) reduce() s = treetostring(root) cleanparse(s) proot = root print "after",NR,treetostring(root) } END{ OFS=":" print pindex, root # for(i in num) # print i,num[i],levels(i) # print "l,r, root:", root # for(i in ile) # print i, ile[i], iri[i] # print num[1], "is at",levels(1),"levels" s = treetostring(root) cleanparse(s) print treetostring(root) reduce() print treetostring(root) print magnitude(root) }