advent-of-code/12021/16/16_2.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
}