diff --git a/18/18_2.awk b/18/18_2.awk new file mode 100644 index 0000000..9a00b22 --- /dev/null +++ b/18/18_2.awk @@ -0,0 +1,174 @@ +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 } + +{ line[NR] = $0 } + +END{ + print NR + maxmag = 0 + for(a=1;a<=NR;a++){ + for(b=1;b<=NR;b++){ + if(a!=b){ + print "parsing", a, b + cleanparse( line[a] ) + proot = root + parse( line[b] ) + num[++pindex] = -1 + ile[pindex] = proot + iri[pindex] = root + root = pindex + reduce() + if(magnitude(root)>maxmag){ + maxmag=magnitude(root) + maxs = treetostring(root) + maxa = a + maxb = b + } + } + } + } + print maxmag, maxs, maxa, maxb +}