🏡 2021/day16.nim

Day 16: Packet Decoder

Today is about parsing a binary signal here is the first example signal to practice one of the basic function I will be using (toBin)

echo 0xD2FE28.toBin(len=24)
echo "VVVTTTAAAAABBBBBCCCCC"
110100101111111000101000
VVVTTTAAAAABBBBBCCCCC

At first I thougth I could try with binaryparse:

import binaryparse, streams

block:
  let test1 = newStringStream("\xD2\xFE\x28")

  createParser(packet):
    u3: version
    u3: typeId
  
  var data = packet.get(test1)
  dump data
data = (version: 6, typeId: 7)

But the result is odd (bug?). So then I could try with binarylang and the first step went better:

import binarylang

block:
  let test1 = newStringBitStream("\xD2\xFE\x28")

  struct(packet):
    u3: version
    u3: typeId

  var data = packet.get(test1)
  # data is an object without a $ proc defined
  echo data.version
  echo data.typeId
6
4

But after this I was lost. I think it can be done with this library and it would be rather cool but what I could gather in limited time from documentation and code was not enough.

So I decided to start from scratch. And let's start with parsing the input. It would be much nicer to use sequence of bytes and keep information compact, but it is much easier to pack a char for each bit (!). I will also be using our standard int for whatever small int comes my way...

func parseHex(c: char): int =
  if c in '0' .. '9':
    ord(c) - ord ('0')
  elif c in 'A' .. 'F':
    10 + ord(c) - ord ('A')
  else:
    0  # should raise error

# parse string to string and waste a lot of info...
func parse(text: string): string =
  for c in text:
    result.add c.parseHex.toBin(len=4)

echo 'A'.parseHex
echo parse "D2FE28"
echo "VVVTTTAAAAABBBBBCCCCC"
10
110100101111111000101000
VVVTTTAAAAABBBBBCCCCC

and then, slowly but surely I went on building my implementation bit by bit, adding debugging stuff and being as usual a bit too verbose. Packet type contains way too much info... but in the end I manage to dots all my _i_s...

It is all spread here without a lot of commentary and possibly with too many outputs.

type
  PacketKind = enum
    pkLiteral, pkOperator
  Packet = ref object
    version: int
    typeId: int
    case kind: PacketKind
    of pkLiteral:
      value: int
    of pkOperator:
      lengthTypeId: char
      totBits: int
      numPackets: int
      packets: seq[Packet]

func `$`(p: Packet): string =
  result = &"Packet(version: {p.version}, typeId: {p.typeId}, kind: {p.kind}"
  case p.kind
  of pkLiteral:
    result &= &", value: {p.value})"
  of pkOperator:
    result &= &", lengthTypeId: {p.lengthTypeId}, totBits: {p.totBits}, numPackets: {p.numPackets}):\n"
    for packet in p.packets:
      result &= indent($packet, 2) & '\n'

var
  packet: Packet
  bits: string

func parseLiteral(bits: string, i: var int): int =
  var
    valueBits: string
    next = true
  while next:
    if bits[i] == '0':
      next = false
    inc i
    valueBits &= bits[i ..< i + 4]
    inc i, 4
  discard valueBits.parseBin(result)

template check =
  # not sure if in the end this is actually an error
  if i >= bits.len:
    #debugEcho "ERR"
    #debugEcho "i: ", i
    #debugEcho "bits.len: ", bits.len
    #debugEcho "packet: ", packet
    return i

proc parsePacket(bits: string, packet: var Packet, start: int): int =
  var i = start
  packet = Packet()
  check
  i += bits.parseBin(packet.version, start=i, maxLen=3)
  check
  i += bits.parseBin(packet.typeId, start=i, maxLen=3)
  check
  if packet.typeId == 4:
    packet = Packet(version: packet.version, typeId: packet.typeId, kind: pkLiteral)
    packet.value = bits.parseLiteral(i)
    check
    return i
  packet = Packet(version: packet.version, typeId: packet.typeId, kind: pkOperator)
  packet.lengthTypeId = bits[i]
  inc i
  check
  var maxBits: int
  if packet.lengthTypeId == '0':
    i += bits.parseBin(packet.totBits, start=i, maxLen=15)
    check
    maxBits = i + packet.totBits
    packet.numPackets = 100
  else:
    i += bits.parseBin(packet.numPackets, start=i, maxLen=11)
    check
    maxBits = int.high
  # debugEcho "i: ", i, "; maxBits: ", maxBits, "; numPackets: ", packet.numPackets
  while i < maxBits and packet.packets.len < packet.numPackets:
    var newPacket = Packet()
    i = bits.parsePacket(newPacket, i)
    #debugEcho "i: ", i
    packet.packets.add newPacket
    check
  return i

func sumVersions(packet: Packet): int =
  result += packet.version
  if packet.kind == pkOperator:
    for p in packet.packets:
      result += sumVersions p

func pvalue(packet: Packet): int = # I already have value for literal
  case packet.typeId
  of 0:
    sum(packet.packets.mapIt(it.pvalue))
  of 1:
    prod(packet.packets.mapIt(it.pvalue))
  of 2:
    min(packet.packets.mapIt(it.pvalue))
  of 3:
    max(packet.packets.mapIt(it.pvalue))
  of 4:
    packet.value
  of 5:
    assert packet.packets.len == 2
    if packet.packets[0].pvalue > packet.packets[1].pvalue:
      1
    else:
      0
  of 6:
    assert packet.packets.len == 2
    if packet.packets[0].pvalue < packet.packets[1].pvalue:
      1
    else:
      0
  of 7:
    assert packet.packets.len == 2
    if packet.packets[0].pvalue == packet.packets[1].pvalue:
      1
    else:
      0
  else:
    0

template example(text: string) =
  echo "example: ", text
  bits = parse text
  discard parsePacket(bits, packet, 0)
  echo packet
  echo "sumVersions: ", packet.sumVersions
  echo "pvalue: ", packet.pvalue

example "D2FE28"
example: D2FE28
Packet(version: 6, typeId: 4, kind: pkLiteral, value: 2021)
sumVersions: 6
pvalue: 2021
example "38006F45291200"
example: 38006F45291200
Packet(version: 1, typeId: 6, kind: pkOperator, lengthTypeId: 0, totBits: 27, numPackets: 100):
  Packet(version: 6, typeId: 4, kind: pkLiteral, value: 10)
  Packet(version: 2, typeId: 4, kind: pkLiteral, value: 20)

sumVersions: 9
pvalue: 1
example "EE00D40C823060"
example: EE00D40C823060
Packet(version: 7, typeId: 3, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 3):
  Packet(version: 2, typeId: 4, kind: pkLiteral, value: 1)
  Packet(version: 4, typeId: 4, kind: pkLiteral, value: 2)
  Packet(version: 1, typeId: 4, kind: pkLiteral, value: 3)

sumVersions: 14
pvalue: 3

Here are a few more examples of hexadecimal-encoded transmissions:

example "8A004A801A8002F478"
example: 8A004A801A8002F478
Packet(version: 4, typeId: 2, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 1):
  Packet(version: 1, typeId: 2, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 1):
    Packet(version: 5, typeId: 2, kind: pkOperator, lengthTypeId: 0, totBits: 11, numPackets: 100):
      Packet(version: 6, typeId: 4, kind: pkLiteral, value: 15)
    
  

sumVersions: 16
pvalue: 15
example "620080001611562C8802118E34"
example: 620080001611562C8802118E34
Packet(version: 3, typeId: 0, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
  Packet(version: 0, typeId: 0, kind: pkOperator, lengthTypeId: 0, totBits: 22, numPackets: 100):
    Packet(version: 0, typeId: 4, kind: pkLiteral, value: 10)
    Packet(version: 5, typeId: 4, kind: pkLiteral, value: 11)
  
  Packet(version: 1, typeId: 0, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
    Packet(version: 0, typeId: 4, kind: pkLiteral, value: 12)
    Packet(version: 3, typeId: 4, kind: pkLiteral, value: 13)
  

sumVersions: 12
pvalue: 46
example "C0015000016115A2E0802F182340"
example: C0015000016115A2E0802F182340
Packet(version: 6, typeId: 0, kind: pkOperator, lengthTypeId: 0, totBits: 84, numPackets: 100):
  Packet(version: 0, typeId: 0, kind: pkOperator, lengthTypeId: 0, totBits: 22, numPackets: 100):
    Packet(version: 0, typeId: 4, kind: pkLiteral, value: 10)
    Packet(version: 6, typeId: 4, kind: pkLiteral, value: 11)
  
  Packet(version: 4, typeId: 0, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
    Packet(version: 7, typeId: 4, kind: pkLiteral, value: 12)
    Packet(version: 0, typeId: 4, kind: pkLiteral, value: 13)
  

sumVersions: 23
pvalue: 46
example "A0016C880162017C3686B18A3D4780"
example: A0016C880162017C3686B18A3D4780
Packet(version: 5, typeId: 0, kind: pkOperator, lengthTypeId: 0, totBits: 91, numPackets: 100):
  Packet(version: 1, typeId: 0, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 1):
    Packet(version: 3, typeId: 0, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 5):
      Packet(version: 7, typeId: 4, kind: pkLiteral, value: 6)
      Packet(version: 6, typeId: 4, kind: pkLiteral, value: 6)
      Packet(version: 5, typeId: 4, kind: pkLiteral, value: 12)
      Packet(version: 2, typeId: 4, kind: pkLiteral, value: 15)
      Packet(version: 2, typeId: 4, kind: pkLiteral, value: 15)
    
  

sumVersions: 31
pvalue: 54
example readFile("2021/input16.txt")
example: 220D69802BE00A0803711E1441B1006E39C318A12730C200DCE66D2CCE360FA0055652CD32966E3004677EDF600B0803B1361741510076254138D8A00E4FFF3E3393ABE4FC7AC10410010799D2A4430003764DBE281802F3102CA00D4840198430EE0E00021D04E3F41F84AE0154DFDE65A17CCBFAFA14ADA56854FE5E3FD5BCC53B0D2598027A00848C63F2B918C7E513DEC3290051B3867E009CCC5FE46BD520007FE5E8AD344B37583D0803E40085475887144C01A8C10FE2B9803B0720D45A3004652FD8FA05F80122CAF91E5F50E66BEF8AB000BB0F4802039C20917B920B9221200ABF0017B9C92CCDC76BD3A8C4012CCB13CB22CDB243E9C3D2002067440400D9BE62DAC4D2DC0249BF76B6F72BE459B279F759AE7BE42E0058801CC059B08018A0070012CEC045BA01006C03A8000D46C02FA000A8EA007200800E00618018E00410034220061801D36BF178C01796FC52B4017100763547E86000084C7E8910AC0027E9B029FE2F4952F96D81B34C8400C24AA8CDAF4F1E98027C00FACDE3BA86982570D13AA640195CD67B046F004662711E989C468C01F1007A10C4C8320008742287117C401A8C715A3FC2C8EB3777540048272DFE7DE1C0149AC8BC9E79D63200B674013978E8BE5E3A2E9AA3CCDD538C01193CFAB0A146006AA00087C3E88B130401D8E304A239802F39FAC922C0169EA3248DF2D600247C89BCDFE9CA7FFD8BB49686236C9FF9795D80C0139BEC4D6C017978CF78C5EB981FCE7D4D801FA9FB63B14789534584010B5802F3467346D2C1D1E080355B00424FC99290C7E5D729586504803A2D005E677F868C271AA479CEEB131592EE5450043A932697E6A92C6E164991EFC4268F25A294600B5002A3393B31CC834B972804D2F3A4FD72B928E59219C9C771EC3DC89D1802135C9806802729694A6E723FD6134C0129A019E600
Packet(version: 1, typeId: 0, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 53):
  Packet(version: 5, typeId: 1, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
    Packet(version: 5, typeId: 7, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
      Packet(version: 4, typeId: 0, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 3):
        Packet(version: 3, typeId: 4, kind: pkLiteral, value: 8)
        Packet(version: 7, typeId: 4, kind: pkLiteral, value: 5)
        Packet(version: 0, typeId: 4, kind: pkLiteral, value: 3)
      
      Packet(version: 3, typeId: 0, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 3):
        Packet(version: 3, typeId: 4, kind: pkLiteral, value: 14)
        Packet(version: 3, typeId: 4, kind: pkLiteral, value: 6)
        Packet(version: 1, typeId: 4, kind: pkLiteral, value: 10)
      
    
    Packet(version: 0, typeId: 4, kind: pkLiteral, value: 817)
  
  Packet(version: 4, typeId: 1, kind: pkOperator, lengthTypeId: 0, totBits: 110, numPackets: 100):
    Packet(version: 3, typeId: 4, kind: pkLiteral, value: 2519282017)
    Packet(version: 7, typeId: 5, kind: pkOperator, lengthTypeId: 0, totBits: 42, numPackets: 100):
      Packet(version: 5, typeId: 4, kind: pkLiteral, value: 1133)
      Packet(version: 1, typeId: 4, kind: pkLiteral, value: 1133)
    
  
  Packet(version: 6, typeId: 1, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
    Packet(version: 1, typeId: 4, kind: pkLiteral, value: 3581)
    Packet(version: 7, typeId: 5, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
      Packet(version: 6, typeId: 0, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 3):
        Packet(version: 5, typeId: 4, kind: pkLiteral, value: 9)
        Packet(version: 5, typeId: 4, kind: pkLiteral, value: 5)
        Packet(version: 6, typeId: 4, kind: pkLiteral, value: 2)
      
      Packet(version: 5, typeId: 0, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 3):
        Packet(version: 5, typeId: 4, kind: pkLiteral, value: 9)
        Packet(version: 2, typeId: 4, kind: pkLiteral, value: 2)
        Packet(version: 3, typeId: 4, kind: pkLiteral, value: 13)
      
    
  
  Packet(version: 4, typeId: 2, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 3):
    Packet(version: 4, typeId: 4, kind: pkLiteral, value: 1047014)
    Packet(version: 3, typeId: 4, kind: pkLiteral, value: 863)
    Packet(version: 4, typeId: 4, kind: pkLiteral, value: 61916)
  
  Packet(version: 0, typeId: 4, kind: pkLiteral, value: 2)
  Packet(version: 0, typeId: 2, kind: pkOperator, lengthTypeId: 0, totBits: 32, numPackets: 100):
    Packet(version: 7, typeId: 4, kind: pkLiteral, value: 2474)
    Packet(version: 4, typeId: 4, kind: pkLiteral, value: 8)
  
  Packet(version: 3, typeId: 0, kind: pkOperator, lengthTypeId: 0, totBits: 27, numPackets: 100):
    Packet(version: 5, typeId: 4, kind: pkLiteral, value: 61)
    Packet(version: 7, typeId: 4, kind: pkLiteral, value: 10)
  
  Packet(version: 0, typeId: 1, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
    Packet(version: 7, typeId: 4, kind: pkLiteral, value: 2053)
    Packet(version: 4, typeId: 5, kind: pkOperator, lengthTypeId: 0, totBits: 106, numPackets: 100):
      Packet(version: 2, typeId: 0, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 3):
        Packet(version: 1, typeId: 4, kind: pkLiteral, value: 4)
        Packet(version: 1, typeId: 4, kind: pkLiteral, value: 7)
        Packet(version: 3, typeId: 4, kind: pkLiteral, value: 3)
      
      Packet(version: 4, typeId: 0, kind: pkOperator, lengthTypeId: 0, totBits: 33, numPackets: 100):
        Packet(version: 6, typeId: 4, kind: pkLiteral, value: 2)
        Packet(version: 3, typeId: 4, kind: pkLiteral, value: 15)
        Packet(version: 6, typeId: 4, kind: pkLiteral, value: 3)
      
    
  
  Packet(version: 7, typeId: 4, kind: pkLiteral, value: 4)
  Packet(version: 5, typeId: 3, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 5):
    Packet(version: 2, typeId: 4, kind: pkLiteral, value: 3071)
    Packet(version: 1, typeId: 4, kind: pkLiteral, value: 25896876792)
    Packet(version: 2, typeId: 4, kind: pkLiteral, value: 90333271)
    Packet(version: 7, typeId: 4, kind: pkLiteral, value: 119514860)
    Packet(version: 2, typeId: 4, kind: pkLiteral, value: 53417)
  
  Packet(version: 3, typeId: 1, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
    Packet(version: 3, typeId: 6, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
      Packet(version: 0, typeId: 4, kind: pkLiteral, value: 70133)
      Packet(version: 3, typeId: 4, kind: pkLiteral, value: 70133)
    
    Packet(version: 0, typeId: 4, kind: pkLiteral, value: 61068)
  
  Packet(version: 5, typeId: 1, kind: pkOperator, lengthTypeId: 0, totBits: 81, numPackets: 100):
    Packet(version: 5, typeId: 4, kind: pkLiteral, value: 198)
    Packet(version: 3, typeId: 7, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
      Packet(version: 3, typeId: 4, kind: pkLiteral, value: 2335)
      Packet(version: 7, typeId: 4, kind: pkLiteral, value: 5594)
    
  
  Packet(version: 2, typeId: 0, kind: pkOperator, lengthTypeId: 0, totBits: 63, numPackets: 100):
    Packet(version: 7, typeId: 4, kind: pkLiteral, value: 1866)
    Packet(version: 6, typeId: 4, kind: pkLiteral, value: 164)
    Packet(version: 5, typeId: 4, kind: pkLiteral, value: 46351)
  
  Packet(version: 2, typeId: 0, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 3):
    Packet(version: 7, typeId: 1, kind: pkOperator, lengthTypeId: 0, totBits: 33, numPackets: 100):
      Packet(version: 2, typeId: 4, kind: pkLiteral, value: 14)
      Packet(version: 5, typeId: 4, kind: pkLiteral, value: 8)
      Packet(version: 3, typeId: 4, kind: pkLiteral, value: 10)
    
    Packet(version: 1, typeId: 1, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 3):
      Packet(version: 2, typeId: 4, kind: pkLiteral, value: 12)
      Packet(version: 0, typeId: 4, kind: pkLiteral, value: 7)
      Packet(version: 7, typeId: 4, kind: pkLiteral, value: 10)
    
    Packet(version: 7, typeId: 1, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 3):
      Packet(version: 5, typeId: 4, kind: pkLiteral, value: 3)
      Packet(version: 4, typeId: 4, kind: pkLiteral, value: 3)
      Packet(version: 2, typeId: 4, kind: pkLiteral, value: 11)
    
  
  Packet(version: 2, typeId: 1, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
    Packet(version: 1, typeId: 4, kind: pkLiteral, value: 75308549)
    Packet(version: 7, typeId: 6, kind: pkOperator, lengthTypeId: 0, totBits: 72, numPackets: 100):
      Packet(version: 5, typeId: 4, kind: pkLiteral, value: 1512)
      Packet(version: 7, typeId: 4, kind: pkLiteral, value: 32762322674)
    
  
  Packet(version: 5, typeId: 3, kind: pkOperator, lengthTypeId: 0, totBits: 11, numPackets: 100):
    Packet(version: 5, typeId: 4, kind: pkLiteral, value: 7)
  
  Packet(version: 5, typeId: 1, kind: pkOperator, lengthTypeId: 0, totBits: 64, numPackets: 100):
    Packet(version: 3, typeId: 4, kind: pkLiteral, value: 196)
    Packet(version: 0, typeId: 4, kind: pkLiteral, value: 31)
    Packet(version: 3, typeId: 4, kind: pkLiteral, value: 33)
    Packet(version: 3, typeId: 4, kind: pkLiteral, value: 36)
  
  Packet(version: 1, typeId: 1, kind: pkOperator, lengthTypeId: 0, totBits: 85, numPackets: 100):
    Packet(version: 7, typeId: 6, kind: pkOperator, lengthTypeId: 0, totBits: 47, numPackets: 100):
      Packet(version: 3, typeId: 4, kind: pkLiteral, value: 3115)
      Packet(version: 1, typeId: 4, kind: pkLiteral, value: 45499)
    
    Packet(version: 6, typeId: 4, kind: pkLiteral, value: 216)
  
  Packet(version: 6, typeId: 1, kind: pkOperator, lengthTypeId: 0, totBits: 75, numPackets: 100):
    Packet(version: 1, typeId: 4, kind: pkLiteral, value: 100)
    Packet(version: 7, typeId: 4, kind: pkLiteral, value: 104)
    Packet(version: 5, typeId: 4, kind: pkLiteral, value: 188)
    Packet(version: 4, typeId: 4, kind: pkLiteral, value: 7)
    Packet(version: 6, typeId: 4, kind: pkLiteral, value: 199)
  
  Packet(version: 5, typeId: 1, kind: pkOperator, lengthTypeId: 0, totBits: 16, numPackets: 100):
    Packet(version: 1, typeId: 4, kind: pkLiteral, value: 210)
  
  Packet(version: 0, typeId: 0, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 1):
    Packet(version: 5, typeId: 4, kind: pkLiteral, value: 3162941497)
  
  Packet(version: 3, typeId: 3, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 4):
    Packet(version: 4, typeId: 4, kind: pkLiteral, value: 819624592872)
    Packet(version: 5, typeId: 4, kind: pkLiteral, value: 180)
    Packet(version: 7, typeId: 4, kind: pkLiteral, value: 254)
    Packet(version: 5, typeId: 4, kind: pkLiteral, value: 708340)
  
  Packet(version: 1, typeId: 3, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 1):
    Packet(version: 3, typeId: 0, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 1):
      Packet(version: 6, typeId: 3, kind: pkOperator, lengthTypeId: 0, totBits: 358, numPackets: 100):
        Packet(version: 6, typeId: 0, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 1):
          Packet(version: 4, typeId: 2, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 1):
            Packet(version: 6, typeId: 0, kind: pkOperator, lengthTypeId: 0, totBits: 300, numPackets: 100):
              Packet(version: 7, typeId: 3, kind: pkOperator, lengthTypeId: 0, totBits: 278, numPackets: 100):
                Packet(version: 7, typeId: 2, kind: pkOperator, lengthTypeId: 0, totBits: 256, numPackets: 100):
                  Packet(version: 3, typeId: 3, kind: pkOperator, lengthTypeId: 0, totBits: 234, numPackets: 100):
                    Packet(version: 0, typeId: 0, kind: pkOperator, lengthTypeId: 0, totBits: 212, numPackets: 100):
                      Packet(version: 3, typeId: 3, kind: pkOperator, lengthTypeId: 0, totBits: 190, numPackets: 100):
                        Packet(version: 4, typeId: 0, kind: pkOperator, lengthTypeId: 0, totBits: 168, numPackets: 100):
                          Packet(version: 7, typeId: 2, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 1):
                            Packet(version: 6, typeId: 2, kind: pkOperator, lengthTypeId: 0, totBits: 128, numPackets: 100):
                              Packet(version: 0, typeId: 3, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 1):
                                Packet(version: 4, typeId: 1, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 1):
                                  Packet(version: 4, typeId: 3, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 1):
                                    Packet(version: 0, typeId: 1, kind: pkOperator, lengthTypeId: 0, totBits: 52, numPackets: 100):
                                      Packet(version: 1, typeId: 0, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 1):
                                        Packet(version: 4, typeId: 1, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 1):
                                          Packet(version: 6, typeId: 4, kind: pkLiteral, value: 187)
                                        
                                      
                                    
                                  
                                
                              
                            
                          
                        
                      
                    
                  
                
              
            
          
        
      
    
  
  Packet(version: 7, typeId: 4, kind: pkLiteral, value: 11)
  Packet(version: 6, typeId: 1, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
    Packet(version: 7, typeId: 4, kind: pkLiteral, value: 28441)
    Packet(version: 2, typeId: 6, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
      Packet(version: 7, typeId: 0, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 3):
        Packet(version: 5, typeId: 4, kind: pkLiteral, value: 13)
        Packet(version: 2, typeId: 4, kind: pkLiteral, value: 15)
        Packet(version: 6, typeId: 4, kind: pkLiteral, value: 6)
      
      Packet(version: 0, typeId: 0, kind: pkOperator, lengthTypeId: 0, totBits: 33, numPackets: 100):
        Packet(version: 1, typeId: 4, kind: pkLiteral, value: 15)
        Packet(version: 6, typeId: 4, kind: pkLiteral, value: 9)
        Packet(version: 0, typeId: 4, kind: pkLiteral, value: 5)
      
    
  
  Packet(version: 3, typeId: 0, kind: pkOperator, lengthTypeId: 0, totBits: 79, numPackets: 100):
    Packet(version: 6, typeId: 4, kind: pkLiteral, value: 176)
    Packet(version: 2, typeId: 4, kind: pkLiteral, value: 4043)
    Packet(version: 6, typeId: 4, kind: pkLiteral, value: 149405)
    Packet(version: 5, typeId: 4, kind: pkLiteral, value: 1)
  
  Packet(version: 5, typeId: 4, kind: pkLiteral, value: 172)
  Packet(version: 4, typeId: 1, kind: pkOperator, lengthTypeId: 0, totBits: 48, numPackets: 100):
    Packet(version: 4, typeId: 4, kind: pkLiteral, value: 90)
    Packet(version: 1, typeId: 4, kind: pkLiteral, value: 187)
    Packet(version: 6, typeId: 4, kind: pkLiteral, value: 231)
  
  Packet(version: 5, typeId: 1, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
    Packet(version: 3, typeId: 7, kind: pkOperator, lengthTypeId: 0, totBits: 62, numPackets: 100):
      Packet(version: 5, typeId: 4, kind: pkLiteral, value: 193831084)
      Packet(version: 0, typeId: 4, kind: pkLiteral, value: 1421)
    
    Packet(version: 0, typeId: 4, kind: pkLiteral, value: 218)
  
  Packet(version: 3, typeId: 1, kind: pkOperator, lengthTypeId: 0, totBits: 101, numPackets: 100):
    Packet(version: 3, typeId: 4, kind: pkLiteral, value: 695560)
    Packet(version: 6, typeId: 7, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
      Packet(version: 1, typeId: 4, kind: pkLiteral, value: 33555)
      Packet(version: 6, typeId: 4, kind: pkLiteral, value: 33555)
    
  
  Packet(version: 2, typeId: 1, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 3):
    Packet(version: 7, typeId: 0, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 3):
      Packet(version: 6, typeId: 4, kind: pkLiteral, value: 4)
      Packet(version: 1, typeId: 4, kind: pkLiteral, value: 9)
      Packet(version: 4, typeId: 4, kind: pkLiteral, value: 3)
    
    Packet(version: 1, typeId: 0, kind: pkOperator, lengthTypeId: 0, totBits: 33, numPackets: 100):
      Packet(version: 6, typeId: 4, kind: pkLiteral, value: 4)
      Packet(version: 2, typeId: 4, kind: pkLiteral, value: 7)
      Packet(version: 0, typeId: 4, kind: pkLiteral, value: 11)
    
    Packet(version: 7, typeId: 0, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 3):
      Packet(version: 2, typeId: 4, kind: pkLiteral, value: 12)
      Packet(version: 3, typeId: 4, kind: pkLiteral, value: 10)
      Packet(version: 6, typeId: 4, kind: pkLiteral, value: 15)
    
  
  Packet(version: 7, typeId: 4, kind: pkLiteral, value: 5)
  Packet(version: 4, typeId: 4, kind: pkLiteral, value: 14)
  Packet(version: 5, typeId: 4, kind: pkLiteral, value: 2942)
  Packet(version: 5, typeId: 2, kind: pkOperator, lengthTypeId: 0, totBits: 36, numPackets: 100):
    Packet(version: 0, typeId: 4, kind: pkLiteral, value: 13040895)
  
  Packet(version: 0, typeId: 3, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
    Packet(version: 4, typeId: 4, kind: pkLiteral, value: 2706)
    Packet(version: 7, typeId: 4, kind: pkLiteral, value: 236764)
  
  Packet(version: 3, typeId: 1, kind: pkOperator, lengthTypeId: 0, totBits: 91, numPackets: 100):
    Packet(version: 1, typeId: 6, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
      Packet(version: 3, typeId: 4, kind: pkLiteral, value: 29093)
      Packet(version: 7, typeId: 4, kind: pkLiteral, value: 29093)
    
    Packet(version: 6, typeId: 4, kind: pkLiteral, value: 2639)
  
  Packet(version: 1, typeId: 4, kind: pkLiteral, value: 2905)
  Packet(version: 6, typeId: 1, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
    Packet(version: 1, typeId: 4, kind: pkLiteral, value: 60706885)
    Packet(version: 0, typeId: 6, kind: pkOperator, lengthTypeId: 0, totBits: 106, numPackets: 100):
      Packet(version: 5, typeId: 0, kind: pkOperator, lengthTypeId: 0, totBits: 33, numPackets: 100):
        Packet(version: 7, typeId: 4, kind: pkLiteral, value: 7)
        Packet(version: 6, typeId: 4, kind: pkLiteral, value: 8)
        Packet(version: 5, typeId: 4, kind: pkLiteral, value: 9)
      
      Packet(version: 4, typeId: 0, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 3):
        Packet(version: 5, typeId: 4, kind: pkLiteral, value: 14)
        Packet(version: 1, typeId: 4, kind: pkLiteral, value: 2)
        Packet(version: 2, typeId: 4, kind: pkLiteral, value: 8)
      
    
  
  Packet(version: 7, typeId: 1, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
    Packet(version: 7, typeId: 4, kind: pkLiteral, value: 849193)
    Packet(version: 0, typeId: 5, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
      Packet(version: 6, typeId: 4, kind: pkLiteral, value: 3660)
      Packet(version: 4, typeId: 4, kind: pkLiteral, value: 6045)
    
  
  Packet(version: 3, typeId: 0, kind: pkOperator, lengthTypeId: 0, totBits: 145, numPackets: 100):
    Packet(version: 7, typeId: 4, kind: pkLiteral, value: 22)
    Packet(version: 7, typeId: 4, kind: pkLiteral, value: 821619064094)
    Packet(version: 6, typeId: 4, kind: pkLiteral, value: 675)
    Packet(version: 0, typeId: 4, kind: pkLiteral, value: 13)
    Packet(version: 5, typeId: 4, kind: pkLiteral, value: 66876028)
  
  Packet(version: 0, typeId: 1, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
    Packet(version: 3, typeId: 4, kind: pkLiteral, value: 48406)
    Packet(version: 5, typeId: 5, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
      Packet(version: 7, typeId: 4, kind: pkLiteral, value: 7781281650951)
      Packet(version: 7, typeId: 4, kind: pkLiteral, value: 3322)
    
  
  Packet(version: 3, typeId: 3, kind: pkOperator, lengthTypeId: 0, totBits: 63, numPackets: 100):
    Packet(version: 2, typeId: 4, kind: pkLiteral, value: 16157976)
    Packet(version: 7, typeId: 4, kind: pkLiteral, value: 9)
    Packet(version: 2, typeId: 4, kind: pkLiteral, value: 165)
  
  Packet(version: 4, typeId: 1, kind: pkOperator, lengthTypeId: 0, totBits: 66, numPackets: 100):
    Packet(version: 6, typeId: 5, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
      Packet(version: 7, typeId: 4, kind: pkLiteral, value: 166)
      Packet(version: 3, typeId: 4, kind: pkLiteral, value: 166)
    
    Packet(version: 6, typeId: 4, kind: pkLiteral, value: 97)
  
  Packet(version: 6, typeId: 4, kind: pkLiteral, value: 15)
  Packet(version: 0, typeId: 1, kind: pkOperator, lengthTypeId: 0, totBits: 106, numPackets: 100):
    Packet(version: 5, typeId: 5, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
      Packet(version: 0, typeId: 4, kind: pkLiteral, value: 1001)
      Packet(version: 4, typeId: 4, kind: pkLiteral, value: 67695326)
    
    Packet(version: 2, typeId: 4, kind: pkLiteral, value: 20632)
  
  Packet(version: 1, typeId: 1, kind: pkOperator, lengthTypeId: 0, totBits: 116, numPackets: 100):
    Packet(version: 2, typeId: 6, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
      Packet(version: 7, typeId: 4, kind: pkLiteral, value: 10219686)
      Packet(version: 0, typeId: 4, kind: pkLiteral, value: 205)
    
    Packet(version: 2, typeId: 4, kind: pkLiteral, value: 483239986)
  
  Packet(version: 5, typeId: 4, kind: pkLiteral, value: 11674)
  Packet(version: 1, typeId: 2, kind: pkOperator, lengthTypeId: 0, totBits: 135, numPackets: 100):
    Packet(version: 2, typeId: 4, kind: pkLiteral, value: 52)
    Packet(version: 6, typeId: 4, kind: pkLiteral, value: 535330074729)
    Packet(version: 1, typeId: 4, kind: pkLiteral, value: 7666)
    Packet(version: 0, typeId: 4, kind: pkLiteral, value: 167)
    Packet(version: 4, typeId: 4, kind: pkLiteral, value: 1561)
  
  Packet(version: 2, typeId: 1, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
    Packet(version: 6, typeId: 5, kind: pkOperator, lengthTypeId: 0, totBits: 42, numPackets: 100):
      Packet(version: 1, typeId: 4, kind: pkLiteral, value: 50028)
      Packet(version: 3, typeId: 4, kind: pkLiteral, value: 144)
    
    Packet(version: 6, typeId: 4, kind: pkLiteral, value: 117)
  
  Packet(version: 6, typeId: 2, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 4):
    Packet(version: 6, typeId: 4, kind: pkLiteral, value: 120864373)
    Packet(version: 3, typeId: 4, kind: pkLiteral, value: 8604)
    Packet(version: 4, typeId: 4, kind: pkLiteral, value: 6)
    Packet(version: 3, typeId: 4, kind: pkLiteral, value: 213436656663)
  
  Packet(version: 2, typeId: 1, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
    Packet(version: 0, typeId: 4, kind: pkLiteral, value: 44080)
    Packet(version: 0, typeId: 6, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
      Packet(version: 3, typeId: 4, kind: pkLiteral, value: 4596286)
      Packet(version: 3, typeId: 4, kind: pkLiteral, value: 129673)
    
  
  Packet(version: 5, typeId: 1, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
    Packet(version: 2, typeId: 4, kind: pkLiteral, value: 160)
    Packet(version: 1, typeId: 4, kind: pkLiteral, value: 236)
  

sumVersions: 1002
pvalue: 1673210814091

For example:

example "C200B40A82"
example: C200B40A82
Packet(version: 6, typeId: 0, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
  Packet(version: 6, typeId: 4, kind: pkLiteral, value: 1)
  Packet(version: 2, typeId: 4, kind: pkLiteral, value: 2)

sumVersions: 14
pvalue: 3
example "04005AC33890"
example: 04005AC33890
Packet(version: 0, typeId: 1, kind: pkOperator, lengthTypeId: 0, totBits: 22, numPackets: 100):
  Packet(version: 5, typeId: 4, kind: pkLiteral, value: 6)
  Packet(version: 3, typeId: 4, kind: pkLiteral, value: 9)

sumVersions: 8
pvalue: 54
example "880086C3E88112"
example: 880086C3E88112
Packet(version: 4, typeId: 2, kind: pkOperator, lengthTypeId: 0, totBits: 33, numPackets: 100):
  Packet(version: 5, typeId: 4, kind: pkLiteral, value: 7)
  Packet(version: 6, typeId: 4, kind: pkLiteral, value: 8)
  Packet(version: 0, typeId: 4, kind: pkLiteral, value: 9)

sumVersions: 15
pvalue: 7
example "CE00C43D881120"
example: CE00C43D881120
Packet(version: 6, typeId: 3, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 3):
  Packet(version: 0, typeId: 4, kind: pkLiteral, value: 7)
  Packet(version: 5, typeId: 4, kind: pkLiteral, value: 8)
  Packet(version: 0, typeId: 4, kind: pkLiteral, value: 9)

sumVersions: 11
pvalue: 9
example "D8005AC2A8F0"
example: D8005AC2A8F0
Packet(version: 6, typeId: 6, kind: pkOperator, lengthTypeId: 0, totBits: 22, numPackets: 100):
  Packet(version: 5, typeId: 4, kind: pkLiteral, value: 5)
  Packet(version: 2, typeId: 4, kind: pkLiteral, value: 15)

sumVersions: 13
pvalue: 1
example "F600BC2D8F"
example: F600BC2D8F
Packet(version: 7, typeId: 5, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
  Packet(version: 7, typeId: 4, kind: pkLiteral, value: 5)
  Packet(version: 5, typeId: 4, kind: pkLiteral, value: 15)

sumVersions: 19
pvalue: 0
example "9C005AC2F8F0"
example: 9C005AC2F8F0
Packet(version: 4, typeId: 7, kind: pkOperator, lengthTypeId: 0, totBits: 22, numPackets: 100):
  Packet(version: 5, typeId: 4, kind: pkLiteral, value: 5)
  Packet(version: 7, typeId: 4, kind: pkLiteral, value: 15)

sumVersions: 16
pvalue: 0
example "9C0141080250320F1802104A08"
example: 9C0141080250320F1802104A08
Packet(version: 4, typeId: 7, kind: pkOperator, lengthTypeId: 0, totBits: 80, numPackets: 100):
  Packet(version: 2, typeId: 0, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
    Packet(version: 2, typeId: 4, kind: pkLiteral, value: 1)
    Packet(version: 4, typeId: 4, kind: pkLiteral, value: 3)
  
  Packet(version: 6, typeId: 1, kind: pkOperator, lengthTypeId: 1, totBits: 0, numPackets: 2):
    Packet(version: 0, typeId: 4, kind: pkLiteral, value: 2)
    Packet(version: 2, typeId: 4, kind: pkLiteral, value: 2)
  

sumVersions: 20
pvalue: 1

That's the right answer! You are one gold star closer to saving your vacation.

That's the right answer! You are one gold star closer to saving your vacation.

import animu, nimib

nbInit(theme=useAdventOfNim)
nbText: """## Day 16: [Packet Decoder](https://adventofcode.com/2021/day/16)

Today is about parsing a binary signal here is the first example
signal to practice one of the basic function I will be using (`toBin`)
"""
nbCode:
  echo 0xD2FE28.toBin(len=24)
  echo "VVVTTTAAAAABBBBBCCCCC"
nbText: """
At first I thougth I could try
with [binaryparse](https://github.com/PMunch/binaryparse):
"""

nbCode:
  import binaryparse, streams

  block:
    let test1 = newStringStream("\xD2\xFE\x28")

    createParser(packet):
      u3: version
      u3: typeId
    
    var data = packet.get(test1)
    dump data
nbText: """
But the result is odd ([bug?](https://github.com/PMunch/binaryparse/issues/18)). So then I could try with
[binarylang](https://github.com/sealmove/binarylang) and the first step went better:
"""
nbCode:
  import binarylang

  block:
    let test1 = newStringBitStream("\xD2\xFE\x28")

    struct(packet):
      u3: version
      u3: typeId

    var data = packet.get(test1)
    # data is an object without a $ proc defined
    echo data.version
    echo data.typeId
nbText: """But after this I was lost. I think it can be done with this library
and it would be rather cool but what I could gather in limited time
from documentation and code was not enough.

So I decided to start from scratch. And let's start with parsing the input.
It would be much nicer to use sequence of bytes and keep information compact,
but it is much easier to pack a `char` for each bit (!). I will also
be using our standard int for whatever small int comes my way...
"""
nbCode:
  func parseHex(c: char): int =
    if c in '0' .. '9':
      ord(c) - ord ('0')
    elif c in 'A' .. 'F':
      10 + ord(c) - ord ('A')
    else:
      0  # should raise error

  # parse string to string and waste a lot of info...
  func parse(text: string): string =
    for c in text:
      result.add c.parseHex.toBin(len=4)

  echo 'A'.parseHex
  echo parse "D2FE28"
  echo "VVVTTTAAAAABBBBBCCCCC"
nbText: """
and then, slowly but surely I went on building my implementation bit by bit,
adding debugging stuff and being as usual a bit too verbose.
Packet type contains way too much info... but in the end I manage to dots all my _i_s...

It is all spread here without a lot of commentary and possibly with too many outputs.
"""
nbCode:
  type
    PacketKind = enum
      pkLiteral, pkOperator
    Packet = ref object
      version: int
      typeId: int
      case kind: PacketKind
      of pkLiteral:
        value: int
      of pkOperator:
        lengthTypeId: char
        totBits: int
        numPackets: int
        packets: seq[Packet]

  func `$`(p: Packet): string =
    result = &"Packet(version: {p.version}, typeId: {p.typeId}, kind: {p.kind}"
    case p.kind
    of pkLiteral:
      result &= &", value: {p.value})"
    of pkOperator:
      result &= &", lengthTypeId: {p.lengthTypeId}, totBits: {p.totBits}, numPackets: {p.numPackets}):\n"
      for packet in p.packets:
        result &= indent($packet, 2) & '\n'

  var
    packet: Packet
    bits: string

  func parseLiteral(bits: string, i: var int): int =
    var
      valueBits: string
      next = true
    while next:
      if bits[i] == '0':
        next = false
      inc i
      valueBits &= bits[i ..< i + 4]
      inc i, 4
    discard valueBits.parseBin(result)

  template check =
    # not sure if in the end this is actually an error
    if i >= bits.len:
      #debugEcho "ERR"
      #debugEcho "i: ", i
      #debugEcho "bits.len: ", bits.len
      #debugEcho "packet: ", packet
      return i

  proc parsePacket(bits: string, packet: var Packet, start: int): int =
    var i = start
    packet = Packet()
    check
    i += bits.parseBin(packet.version, start=i, maxLen=3)
    check
    i += bits.parseBin(packet.typeId, start=i, maxLen=3)
    check
    if packet.typeId == 4:
      packet = Packet(version: packet.version, typeId: packet.typeId, kind: pkLiteral)
      packet.value = bits.parseLiteral(i)
      check
      return i
    packet = Packet(version: packet.version, typeId: packet.typeId, kind: pkOperator)
    packet.lengthTypeId = bits[i]
    inc i
    check
    var maxBits: int
    if packet.lengthTypeId == '0':
      i += bits.parseBin(packet.totBits, start=i, maxLen=15)
      check
      maxBits = i + packet.totBits
      packet.numPackets = 100
    else:
      i += bits.parseBin(packet.numPackets, start=i, maxLen=11)
      check
      maxBits = int.high
    # debugEcho "i: ", i, "; maxBits: ", maxBits, "; numPackets: ", packet.numPackets
    while i < maxBits and packet.packets.len < packet.numPackets:
      var newPacket = Packet()
      i = bits.parsePacket(newPacket, i)
      #debugEcho "i: ", i
      packet.packets.add newPacket
      check
    return i

  func sumVersions(packet: Packet): int =
    result += packet.version
    if packet.kind == pkOperator:
      for p in packet.packets:
        result += sumVersions p

  func pvalue(packet: Packet): int = # I already have value for literal
    case packet.typeId
    of 0:
      sum(packet.packets.mapIt(it.pvalue))
    of 1:
      prod(packet.packets.mapIt(it.pvalue))
    of 2:
      min(packet.packets.mapIt(it.pvalue))
    of 3:
      max(packet.packets.mapIt(it.pvalue))
    of 4:
      packet.value
    of 5:
      assert packet.packets.len == 2
      if packet.packets[0].pvalue > packet.packets[1].pvalue:
        1
      else:
        0
    of 6:
      assert packet.packets.len == 2
      if packet.packets[0].pvalue < packet.packets[1].pvalue:
        1
      else:
        0
    of 7:
      assert packet.packets.len == 2
      if packet.packets[0].pvalue == packet.packets[1].pvalue:
        1
      else:
        0
    else:
      0

  template example(text: string) =
    echo "example: ", text
    bits = parse text
    discard parsePacket(bits, packet, 0)
    echo packet
    echo "sumVersions: ", packet.sumVersions
    echo "pvalue: ", packet.pvalue

  example "D2FE28"

nbCode: example "38006F45291200"
nbCode: example "EE00D40C823060"
nbText: """
> Here are a few more examples of hexadecimal-encoded transmissions:
> 
> - `8A004A801A8002F478` represents an operator packet (version 4) which contains an operator packet (version 1) which contains an operator packet (version 5) which contains a literal value (version 6); this packet has a version sum of 16.
> - `620080001611562C8802118E34` represents an operator packet (version 3) which contains two sub-packets; each sub-packet is an operator packet that contains two literal values. This packet has a version sum of 12.
> - `C0015000016115A2E0802F182340` has the same structure as the previous example, but the outermost packet uses a different length type ID. This packet has a version sum of 23.
> - `A0016C880162017C3686B18A3D4780` is an operator packet that contains an operator packet that contains an operator packet that contains five literal values; it has a version sum of 31.
"""
nbCode: example "8A004A801A8002F478"
nbCode: example "620080001611562C8802118E34"
nbCode: example "C0015000016115A2E0802F182340"
nbCode: example "A0016C880162017C3686B18A3D4780"
nbCode: example readFile("2021/input16.txt")
nbText: """
> For example:
>
> - `C200B40A82` finds the sum of 1 and 2, resulting in the value 3.
> - `04005AC33890` finds the product of 6 and 9, resulting in the value 54.
> - `880086C3E88112` finds the minimum of 7, 8, and 9, resulting in the value 7.
> - `CE00C43D881120` finds the maximum of 7, 8, and 9, resulting in the value 9.
> - `D8005AC2A8F0` produces 1, because 5 is less than 15.
> - `F600BC2D8F` produces 0, because 5 is not greater than 15.
> - `9C005AC2F8F0` produces 0, because 5 is not equal to 15.
> - `9C0141080250320F1802104A08` produces 1, because 1 + 3 = 2 * 2.
"""
nbCode: example "C200B40A82"
nbCode: example "04005AC33890"
nbCode: example "880086C3E88112"
nbCode: example "CE00C43D881120"
nbCode: example "D8005AC2A8F0"
nbCode: example "F600BC2D8F"
nbCode: example "9C005AC2F8F0"
nbCode: example "9C0141080250320F1802104A08"
gotTheStar
gotTheStar
nbSave