150 lines
3.2 KiB
Awk
150 lines
3.2 KiB
Awk
function strtobin(s){
|
|
bin = ""
|
|
for(i=1;i<=length(s);i++){
|
|
c = substr(s,i,1)
|
|
if(c=="0") b="0000"
|
|
if(c=="1") b="0001"
|
|
if(c=="2") b="0010"
|
|
if(c=="3") b="0011"
|
|
if(c=="4") b="0100"
|
|
if(c=="5") b="0101"
|
|
if(c=="6") b="0110"
|
|
if(c=="7") b="0111"
|
|
if(c=="8") b="1000"
|
|
if(c=="9") b="1001"
|
|
if(c=="A") b="1010"
|
|
if(c=="B") b="1011"
|
|
if(c=="C") b="1100"
|
|
if(c=="D") b="1101"
|
|
if(c=="E") b="1110"
|
|
if(c=="F") b="1111"
|
|
bin = bin b
|
|
}
|
|
return bin
|
|
}
|
|
function bin2num(b){
|
|
num = 0
|
|
n=length(b)
|
|
for(i=1;i<=n;i++){
|
|
bit = substr(b,i,1)
|
|
num += lshift(bit,n-i)
|
|
}
|
|
return num
|
|
}
|
|
function operate(n){
|
|
delete val
|
|
sum = 0; prod=1; min=lit[litsp]; max=0;
|
|
for(i=1;i<=n;i++){
|
|
val[i] = lit[litsp--]
|
|
sum += val[i]
|
|
prod *= val[i]
|
|
if(val[i]<min) min = val[i]
|
|
if(val[i]>max) max = val[i]
|
|
}
|
|
op = ops[osp--]
|
|
if(op==0) result = sum
|
|
if(op==1) result = prod
|
|
if(op==2) result = min
|
|
if(op==3) result = max
|
|
if(op==5) result = (val[2]>val[1])
|
|
if(op==6) result = (val[2]<val[1])
|
|
if(op==7) result = (val[2]==val[1])
|
|
lit[++litsp] = result
|
|
print "operation",op,"with",n,"values; result",result,"(litsp",litsp,")"
|
|
|
|
}
|
|
|
|
function subbits(n){
|
|
# print "minus", n, "bits"
|
|
for(i=1;i<=b2csp;i++){
|
|
b2c[i] -= n
|
|
}
|
|
}
|
|
{
|
|
p = strtobin($0)
|
|
# print p
|
|
}
|
|
END{
|
|
versionc = 0
|
|
checkbits = 0
|
|
checknsub = 0
|
|
litsp = 0
|
|
while( bin2num(p) > 0){
|
|
version = bin2num(substr(p,1,3))
|
|
versionc += version
|
|
p = substr(p,4)
|
|
typeid = bin2num( substr(p,1,3) )
|
|
p = substr(p,4)
|
|
print "---------------"
|
|
print "packet typeid", typeid
|
|
if(b2csp>0 && checkbits){
|
|
print "bits to check",b2c[b2csp]
|
|
subbits( 6 )
|
|
}
|
|
if(s2csp>0 && checknsub && check[checksp]=="n"){
|
|
print "subpackets to check:", s2c[s2csp]
|
|
s2c[s2csp]--;
|
|
}
|
|
if(typeid == 4){
|
|
print "literal"
|
|
pnum = ""
|
|
do{
|
|
startbit = substr(p,1,1)
|
|
num = substr(p,2,4)
|
|
p = substr(p,6)
|
|
if(b2csp>0 && checkbits) subbits( 5 )
|
|
# print startbit, num
|
|
pnum = pnum num
|
|
}while(startbit==1)
|
|
rnum = bin2num(pnum)
|
|
lit[++litsp] = rnum
|
|
print "value:", rnum, "litsp",litsp
|
|
}
|
|
else{
|
|
print "operator", typeid
|
|
ops[++osp] = typeid
|
|
lengthid = substr(p,1,1)
|
|
p = substr(p,2)
|
|
if(lengthid==0){
|
|
len = bin2num( substr(p,1,15) )
|
|
if(b2csp>0 && checkbits) subbits( 16 )
|
|
print "len bits to check",len, litsp
|
|
b2c[++b2csp] = len
|
|
litsv[++litsvsp] = litsp
|
|
check[++checksp] = "b"
|
|
checkbits = 1
|
|
p = substr(p,16)
|
|
}
|
|
else{ #lengthid == 1
|
|
nsub = bin2num( substr(p,1,11) )
|
|
if(b2csp>0 && checkbits) subbits( 12 )
|
|
s2c[++s2csp] = nsub
|
|
nsubs[++nsubssp] = nsub
|
|
check[++checksp] = "n"
|
|
checknsub = 1
|
|
print "n subpackets", nsub
|
|
p = substr(p,12)
|
|
}
|
|
} #end operator
|
|
while((check[checksp]=="n" && checknsub && s2c[s2csp]==0) || (check[checksp]=="b" && checkbits && b2c[b2csp]==0)){
|
|
if(check[checksp]=="n" && s2c[s2csp]==0 && checknsub ){
|
|
n = nsubs[nsubssp--]; n2csp--;
|
|
if(--s2csp==0) checknsub=0;
|
|
checksp--;
|
|
print "nsub done", n, s2csp
|
|
operate(n)
|
|
|
|
}
|
|
else if( check[checksp]=="b" && b2c[b2csp]==0 && checkbits ){
|
|
print "bits done"; b2csp--;
|
|
if(b2csp==0) checkbits=0;
|
|
|
|
checksp--;
|
|
n = litsp-litsv[litsvsp--]
|
|
operate(n)
|
|
}
|
|
}
|
|
}
|
|
print "pt1 sum of versions:", versionc
|
|
}
|