Learning Python with Advent of Code Walkthroughs

Dazbo's Advent of Code solutions, written in Python

Hexadecimal data

Advent of Code 2021 - Day 16

Day 16: Packet Decoder

Useful Links

Concepts and Packages Demonstrated

binary and hexadecimalString format

recursionmultiplying str

Problem Intro

Urgh. This one was brutal. Up until this challenge, all the solutions here took me under two hours. This one took me half a day.

It’s not that hard. But it takes quite a bit of time to fully understand the instructions, and it’s really easy to make mistakes. Fortunately, the problem does come with a lot of examples to work through, which I found to be essential in debugging my solution. I’d also recommend generous use of debug statements as you work your way through!

So, we’re told that we’ve received a transmission in a proprietary BITS format, which is received as a stream of hexadecimal values.

The transmission contains a single outer packet, which in turn contains multiple adjacent inner packets. Each of these inner packets can contain yet more inner packets, and so on.

Although the actual input will only be a single hex stream on a single line, we’ve been given quite a few samples to work through. So, my sample data includes a bunch of these samples:

C200B40A82
04005AC33890
880086C3E88112
CE00C43D881120
D8005AC2A8F0
F600BC2D8F
9C005AC2F8F0
9C0141080250320F1802104A08
A0016C880162017C3686B18A3D4780

We’re told an individual packet has a structure like this:

vvvttt[n*p][x*0]

where:

If a literal packet:

If an operator packet:

Part 1

We’re asked to find the sum of all the version numbers in the input data. Since packets can contain other packets, this lends itself to a recursive solution. Each packet will either contain other packets, or itself be a leaf node.

Before we crack on with the code, let’s just break down one of the examples:

A    0    0    1    6    C    8    8    0    1    6    2    0    1    7    C    3    6    8    6    B    1    8    A    3    D    4    7    8    0    (HEX)
1010 0000 0000 0001 0110 1100 1000 1000 0000 0001 0110 0010 0000 0001 0111 1100 0011 0110 1000 0110 1011 0001 1000 1010 0011 1101 0100 0111 1000 0000 (BIN)

101000000000000101101100100010000000000101100010000000010111110000110110100001101011000110001010001111010100011110000000 (Lvl 0)
V=5       Version=5                                                                                             5
   T=0    Type=Operator													 
      0	Len ID=0, so 15-bit repr of number of bits in subpackets
       000000001011011	Sub-packets are 91 bits in total
                      0010001000000000010110001000000001011111000011011010000110101100011000101000111101010001111  (Lvl 1)
                      V=1                                                                                       1
                         T=0
                            1   Len ID=1, so 11-bit repr of subpackets
 	                     00000000001	  1 sub-packet
                                        0110001000000001011111000011011010000110101100011000101000111101010001111  (Lvl 2)
                                        V=3                                                                     3
                                           T=0
                                              1   Len ID=1, so 11-bit repr of subpackets
                                               00000000101   so 5 subpackets
                                                          1111000011011010000110101100011000101000111101010001111  (Lvl 3)
                                                          V=7        V=6        V=5        V=2        V=2      22
                                                             T=4        T=4        T=4        T=4        T=4
                                                                00110      00110      01100      01111      01111
                                                                                                        TOTAL: 31

So this is the design of my solution:

Let’s start by reading in the data:

input_file = os.path.join(SCRIPT_DIR, INPUT_FILE)
with open(input_file, mode="rt") as f:
    # Each line has a single outer packet. Actual input is only one line, but our test data has many lines.
    outer_packets_data = [hex_to_bin(line) for line in f.read().splitlines()]

for outer_packet_data in outer_packets_data:
    packet = Packet(outer_packet_data)
    logger.info(packet)

def hex_to_bin(hex_value) -> str:
    """ Convert all hex digits to binary representation, with leading zeroes """
    bin_len = 4*len(hex_value)      # 4 bits per hex
    return "{0:0{width}b}".format(int(hex_value, 16), width=bin_len)

We:

Now let’s look at the Packet class itself:

class Packet():
    """ Processes a BITS packet, including recursive processing of any inner packets. """
    VER_START = 0
    TYPE_START = 3
    VAL_START = 6
    
    def __init__(self, bin_input_stream: str, level=0) -> None:
        """ Creates a packet instance. Expects the input as str of bits. 
        Nesting level defaults to 0. Sub-packets have level incremented automatically. """
        
        self._bin_in_str = bin_input_stream     # The raw binary data given to the class
        self._processed_bin_digits = 0  # Increment this throughout stages
        self._level = level     # Nesting level.  Starts at level 0

        logger.debug("Lvl=%s: raw bin=%s", self._level, self._bin_in_str)
        
        self._literal_val = 0
        self._sub_packets: list[Packet] = []      # any nested packets
        self._version = int(self._bin_in_str[Packet.VER_START:Packet.TYPE_START], 2)
        self._processed_bin_digits += Packet.TYPE_START
        
        self._process_type()    # evaluate if literal or operation type and process accordingly
        self._bin_in_self = bin_input_stream[0:self._processed_bin_digits]   # All the bits that represent this packet
        self._remaining_from_stream = bin_input_stream[self._processed_bin_digits:] # Bits we haven't yet consumed from input
    
    def __len__(self):
        """ The length of this packet (including subpackets), but excluding extraneous data from the input stream """
        return len(self._bin_in_self)
               
    @property
    def version_sum(self) -> int:
        """ The sum of the version of this packet, as well as the versions of all subpackets. """
        return self._version + sum(sub_packet.version_sum for sub_packet in self._sub_packets)

    @property
    def value(self) -> int:
        """ Determine value for this type of packet, recursively. """
        return self._literal_val

    @property
    def remaining_from_stream(self):
        """ Returns unconsumed BINARY digits. """
        return self._remaining_from_stream
      
    def _process_type(self):
        """ Determine whether literal (type 4) or operator (type other) packet """
        self._type = int(self._bin_in_str[Packet.TYPE_START:Packet.VAL_START], 2)
        self._processed_bin_digits += Packet.VAL_START - Packet.TYPE_START
        if self._type == 4: # literal
            self._literal_val = self._process_literal()
        else: # operator
            self._process_operator()
            
    def _process_literal(self):
        """ [5*l] where each block of 5 bits starts with a 1, except the last. """
        grp_len = 5
        # grab groups one at a time, until we grab the one starting with a 0
        
        groups_start = Packet.VAL_START
        grps = ""
        while True:
            group = self._bin_in_str[groups_start:groups_start + grp_len]
            grps += group[1:]  # Not interested in first digit of each group
            self._processed_bin_digits += grp_len
            if group[0] == '0':   # this is the last group
                break
            
            groups_start += grp_len 
        
        self._literal_bin = grps
        return int(self._literal_bin, 2) 

    def _process_operator(self):
        """ If m=0, next 15 bits are total length of subpackets: [m[bbbbbbbbbbbbbbb]s*[]]
        If m=1, next 11 bits are the number of subsequent subpackets """
        SUBPACKETS_LEN_FIELD_SZ = 15
        SUBPACKETS_CONTAINED_FIELD_SZ = 11
        
        len_type_id = int(self._bin_in_str[Packet.VAL_START])
        self._processed_bin_digits += 1
        
        if len_type_id == 0: 
            # Next 15 bits is number that represents total length (in bits) of subpackets

            sub_packets_start = Packet.VAL_START+1+SUBPACKETS_LEN_FIELD_SZ
            self._processed_bin_digits += SUBPACKETS_LEN_FIELD_SZ
            sub_packets_total_len = int(self._bin_in_str[Packet.VAL_START+1: sub_packets_start], 2)
            sub_packets_end = sub_packets_start + sub_packets_total_len
            
            # Extract the portion of this packet that contains all the sub_packets
            sub_packets_data = self._bin_in_str[sub_packets_start: sub_packets_end]
            
            # Parse these subpackets sequentially, until no more remain
            processed_bits = 0
            while processed_bits < sub_packets_total_len:
                sub_packet = Packet(sub_packets_data, self._level+1)
                processed_bits += len(sub_packet)
                self._sub_packets.append(sub_packet)
                sub_packets_data = sub_packet.remaining_from_stream
            
            self._processed_bin_digits += sub_packets_total_len
        else:
            # Next 11 bits are mumber that represents number of sub-packets contained       
            assert len_type_id == 1, "Len_type must be 0 or 1"
            self._processed_bin_digits += SUBPACKETS_CONTAINED_FIELD_SZ

            sub_packets_start = Packet.VAL_START+1+SUBPACKETS_CONTAINED_FIELD_SZ
            num_subpackets = int(self._bin_in_str[Packet.VAL_START+1: sub_packets_start], 2)
            sub_packets_data = self._bin_in_str[sub_packets_start:]
            
            # Parse these n subpackets sequentially, until no more remain
            processed_bits = 0
            while len(self._sub_packets) < num_subpackets:
                sub_packet = Packet(sub_packets_data, self._level+1)
                processed_bits += len(sub_packet)
                self._sub_packets.append(sub_packet)
                sub_packets_data = sub_packet.remaining_from_stream 
            
            self._processed_bin_digits += processed_bits               
            
    def __str__(self) -> str:
        """ Short representation at top level only """
        hex_repr = hex(int(self._bin_in_str, 2)).upper()[2:]
        show_len = 10
        if len(hex_repr) > show_len:
            hex_repr = hex_repr[:show_len] + "..."
        
        return (f"Packet:LVL={self._level},VerSum={self.version_sum},Ver={self._version}," + 
                 f"T={self._type},Val={self.value},hex={hex_repr}")
    
    def __repr__(self) -> str:
        """ Show packet information, including recursive detail """
        if self._sub_packets:
            val = ",".join(repr(sub_packet) for sub_packet in self._sub_packets)
        else:
            val = self._literal_val
            
        return ("\n" + ("  " * self._level) 
                + f"[Packet:LVL={self._level},VerSum={self.version_sum},Ver={self._version},T={self._type},value={val}]")

It works like this:

Other methods worth mentioning:

And finally, a note on representing the object:

To demonstrate these two in action, we’ll test using our A0016C880162017C3686B18A3D4780 sample. First, using __str__():

print(packet)

Output:

Packet:LVL=0,VerSum=31,Ver=5,T=0,Val=0,hex=A0016C8801...

And now using __repr__():

print(repr(packet))

Output:

[Packet:LVL=0,VerSum=31,Ver=5,T=0,value=
  [Packet:LVL=1,VerSum=26,Ver=1,T=0,value=
    [Packet:LVL=2,VerSum=25,Ver=3,T=0,value=
      [Packet:LVL=3,VerSum=7,Ver=7,T=4,value=6],
      [Packet:LVL=3,VerSum=6,Ver=6,T=4,value=6],
      [Packet:LVL=3,VerSum=5,Ver=5,T=4,value=12],
      [Packet:LVL=3,VerSum=2,Ver=2,T=4,value=15],
      [Packet:LVL=3,VerSum=2,Ver=2,T=4,value=15]]]]

Notice how the __repr()__ version mirrors the worked example from above. This version is extremely helpful when debugging!

Part 2

Now we’re asked to calculate the value of the transmission. This is entirely dependent on the type ID, and we’re told that each type requies a different form of processing. I.e.

Type ID Operation
0Sum value of subpackets. If only one sub-packet, then return the value of the subpacket.
1Product of values of subpackets. If only one sub-packet, return the value of the subpacket.
2Minimum of values of all subpackets.
3Maximum of values of all subpackets.
4Return _literal_val
51 if first subpacket > than second subpacket, else 0.
61 if first subpacket < than second subpacket, else 0.
71 if first subpacket == second subpacket, else 0.

There’s very little we need to do. In fact, the only change required is to the value property in our Packet class. The new version still returns self._literal_val for the _type == 4 case, but otherwise recurses into subpackets, as required for each operation.

    @property
    def value(self) -> int:
        """ Determine value for this type of packet, recursively. """
        val = 0
        
        if self._type == 0:  # recursive sum of values
            for sub_packet in self._sub_packets:
                val += sub_packet.value
        elif self._type == 1:   # recursive product of values
            val = 1
            for sub_packet in self._sub_packets:
                val *= sub_packet.value
        elif self._type == 2:   # minimum of sub-packets
            val = min(sub_packet.value for sub_packet in self._sub_packets)
        elif self._type == 3:   # maximum of sub-packets
            val = max(sub_packet.value for sub_packet in self._sub_packets)
        elif self._type == 4:   # return the value encoding in the literal (type 4) packet
            val = self._literal_val
        elif self._type == 5:   # 1 if 1st packet > 2nd packet, else 0
            val = 1 if self._sub_packets[0].value > self._sub_packets[1].value else 0
        elif self._type == 6:   # 1 if 1st packet < 2nd packet, else 0
            val = 1 if self._sub_packets[0].value < self._sub_packets[1].value else 0
        elif self._type == 7:   # 1 if 1st packet == 2nd packet, else 0
            val = 1 if self._sub_packets[0].value == self._sub_packets[1].value else 0
        else:
            assert False, "We should never get here!"
            
        return val

So the final output looks something like this:

19:42:00.324:INFO:__main__:     Packet:LVL=0,VerSum=977,Ver=1,T=0,Val=101501020883,hex=220D4B8049...
19:42:00.325:INFO:__main__:     Execution time: 0.0024 seconds

And, just in case you were wondering what the __repr__() would look like…

[Packet:LVL=0,VerSum=977,Ver=1,T=0,value=
  [Packet:LVL=1,VerSum=24,Ver=1,T=3,value=
    [Packet:LVL=2,VerSum=4,Ver=4,T=4,value=15],
    [Packet:LVL=2,VerSum=7,Ver=7,T=4,value=199071281],
    [Packet:LVL=2,VerSum=7,Ver=7,T=4,value=499],
    [Packet:LVL=2,VerSum=5,Ver=5,T=4,value=190]],
  [Packet:LVL=1,VerSum=20,Ver=6,T=1,value=
    [Packet:LVL=2,VerSum=2,Ver=2,T=4,value=240],
    [Packet:LVL=2,VerSum=12,Ver=4,T=5,value=
      [Packet:LVL=3,VerSum=7,Ver=7,T=4,value=3410],
      [Packet:LVL=3,VerSum=1,Ver=1,T=4,value=201]]],
  [Packet:LVL=1,VerSum=8,Ver=7,T=3,value=
    [Packet:LVL=2,VerSum=1,Ver=1,T=4,value=7]],
  [Packet:LVL=1,VerSum=38,Ver=5,T=1,value=
    [Packet:LVL=2,VerSum=4,Ver=4,T=4,value=51786],
    [Packet:LVL=2,VerSum=29,Ver=4,T=7,value=
      [Packet:LVL=3,VerSum=16,Ver=2,T=0,value=
        [Packet:LVL=4,VerSum=5,Ver=5,T=4,value=15],
        [Packet:LVL=4,VerSum=3,Ver=3,T=4,value=11],
        [Packet:LVL=4,VerSum=6,Ver=6,T=4,value=14]],
      [Packet:LVL=3,VerSum=9,Ver=6,T=0,value=
        [Packet:LVL=4,VerSum=0,Ver=0,T=4,value=6],
        [Packet:LVL=4,VerSum=3,Ver=3,T=4,value=11],
        [Packet:LVL=4,VerSum=0,Ver=0,T=4,value=5]]]],
  [Packet:LVL=1,VerSum=5,Ver=5,T=4,value=2513],
  [Packet:LVL=1,VerSum=27,Ver=7,T=1,value=
    [Packet:LVL=2,VerSum=2,Ver=2,T=4,value=28408],
    [Packet:LVL=2,VerSum=18,Ver=6,T=5,value=
      [Packet:LVL=3,VerSum=5,Ver=5,T=4,value=52653],
      [Packet:LVL=3,VerSum=7,Ver=7,T=4,value=52653]]],
  [Packet:LVL=1,VerSum=4,Ver=4,T=4,value=751],
  [Packet:LVL=1,VerSum=5,Ver=5,T=4,value=936579],
  [Packet:LVL=1,VerSum=9,Ver=2,T=1,value=
    [Packet:LVL=2,VerSum=5,Ver=5,T=4,value=84],
    [Packet:LVL=2,VerSum=2,Ver=0,T=5,value=
      [Packet:LVL=3,VerSum=2,Ver=2,T=4,value=246356739],
      [Packet:LVL=3,VerSum=0,Ver=0,T=4,value=15228190]]],
  [Packet:LVL=1,VerSum=27,Ver=3,T=1,value=
    [Packet:LVL=2,VerSum=6,Ver=6,T=4,value=321243],
    [Packet:LVL=2,VerSum=18,Ver=7,T=7,value=
      [Packet:LVL=3,VerSum=4,Ver=4,T=4,value=212],
      [Packet:LVL=3,VerSum=7,Ver=7,T=4,value=631]]],
  [Packet:LVL=1,VerSum=16,Ver=4,T=1,value=
    [Packet:LVL=2,VerSum=10,Ver=3,T=7,value=
      [Packet:LVL=3,VerSum=1,Ver=1,T=4,value=208],
      [Packet:LVL=3,VerSum=6,Ver=6,T=4,value=208]],
    [Packet:LVL=2,VerSum=2,Ver=2,T=4,value=54640]],
  [Packet:LVL=1,VerSum=16,Ver=4,T=1,value=
    [Packet:LVL=2,VerSum=0,Ver=0,T=4,value=41],
    [Packet:LVL=2,VerSum=1,Ver=1,T=4,value=169],
    [Packet:LVL=2,VerSum=4,Ver=4,T=4,value=213],
    [Packet:LVL=2,VerSum=7,Ver=7,T=4,value=246]],
  [Packet:LVL=1,VerSum=16,Ver=2,T=1,value=
    [Packet:LVL=2,VerSum=12,Ver=7,T=6,value=
      [Packet:LVL=3,VerSum=1,Ver=1,T=4,value=34],
      [Packet:LVL=3,VerSum=4,Ver=4,T=4,value=34]],
    [Packet:LVL=2,VerSum=2,Ver=2,T=4,value=31562]],
  [Packet:LVL=1,VerSum=7,Ver=2,T=0,value=
    [Packet:LVL=2,VerSum=5,Ver=5,T=4,value=1625637177]],
  [Packet:LVL=1,VerSum=15,Ver=2,T=3,value=
    [Packet:LVL=2,VerSum=6,Ver=6,T=4,value=852],
    [Packet:LVL=2,VerSum=0,Ver=0,T=4,value=650304435],
    [Packet:LVL=2,VerSum=3,Ver=3,T=4,value=1],
    [Packet:LVL=2,VerSum=1,Ver=1,T=4,value=651481],
    [Packet:LVL=2,VerSum=3,Ver=3,T=4,value=70]],
  [Packet:LVL=1,VerSum=26,Ver=6,T=0,value=
    [Packet:LVL=2,VerSum=4,Ver=4,T=4,value=409369],
    [Packet:LVL=2,VerSum=2,Ver=2,T=4,value=4146254],
    [Packet:LVL=2,VerSum=4,Ver=4,T=4,value=19617],
    [Packet:LVL=2,VerSum=7,Ver=7,T=4,value=217],
    [Packet:LVL=2,VerSum=3,Ver=3,T=4,value=45]],
  [Packet:LVL=1,VerSum=4,Ver=4,T=4,value=13360882],
  [Packet:LVL=1,VerSum=5,Ver=0,T=1,value=
    [Packet:LVL=2,VerSum=1,Ver=1,T=4,value=118],
    [Packet:LVL=2,VerSum=4,Ver=4,T=4,value=106],
    [Packet:LVL=2,VerSum=0,Ver=0,T=4,value=171]],
  [Packet:LVL=1,VerSum=3,Ver=3,T=4,value=10570687],
  [Packet:LVL=1,VerSum=17,Ver=4,T=1,value=
    [Packet:LVL=2,VerSum=11,Ver=0,T=6,value=
      [Packet:LVL=3,VerSum=6,Ver=6,T=4,value=33],
      [Packet:LVL=3,VerSum=5,Ver=5,T=4,value=3854067120]],
    [Packet:LVL=2,VerSum=2,Ver=2,T=4,value=2456541]],
  [Packet:LVL=1,VerSum=18,Ver=4,T=3,value=
    [Packet:LVL=2,VerSum=4,Ver=4,T=4,value=55],
    [Packet:LVL=2,VerSum=3,Ver=3,T=4,value=42444],
    [Packet:LVL=2,VerSum=7,Ver=7,T=4,value=6]],
  [Packet:LVL=1,VerSum=48,Ver=0,T=1,value=
    [Packet:LVL=2,VerSum=45,Ver=3,T=6,value=
      [Packet:LVL=3,VerSum=22,Ver=5,T=0,value=
        [Packet:LVL=4,VerSum=7,Ver=7,T=4,value=15],
        [Packet:LVL=4,VerSum=6,Ver=6,T=4,value=3],
        [Packet:LVL=4,VerSum=4,Ver=4,T=4,value=6]],
      [Packet:LVL=3,VerSum=20,Ver=4,T=0,value=
        [Packet:LVL=4,VerSum=7,Ver=7,T=4,value=5],
        [Packet:LVL=4,VerSum=6,Ver=6,T=4,value=12],
        [Packet:LVL=4,VerSum=3,Ver=3,T=4,value=5]]],
    [Packet:LVL=2,VerSum=3,Ver=3,T=4,value=5833350]],
  [Packet:LVL=1,VerSum=15,Ver=3,T=1,value=
    [Packet:LVL=2,VerSum=12,Ver=7,T=6,value=
      [Packet:LVL=3,VerSum=3,Ver=3,T=4,value=2729],
      [Packet:LVL=3,VerSum=2,Ver=2,T=4,value=15305503]],
    [Packet:LVL=2,VerSum=0,Ver=0,T=4,value=101077955]],
  [Packet:LVL=1,VerSum=16,Ver=5,T=0,value=
    [Packet:LVL=2,VerSum=2,Ver=2,T=4,value=155057593],
    [Packet:LVL=2,VerSum=3,Ver=3,T=4,value=13],
    [Packet:LVL=2,VerSum=0,Ver=0,T=4,value=37107853833],
    [Packet:LVL=2,VerSum=6,Ver=6,T=4,value=5]],
  [Packet:LVL=1,VerSum=18,Ver=6,T=2,value=
    [Packet:LVL=2,VerSum=7,Ver=7,T=4,value=10082448],
    [Packet:LVL=2,VerSum=2,Ver=2,T=4,value=410034],
    [Packet:LVL=2,VerSum=3,Ver=3,T=4,value=1891]],
  [Packet:LVL=1,VerSum=10,Ver=5,T=1,value=
    [Packet:LVL=2,VerSum=5,Ver=5,T=4,value=138]],
  [Packet:LVL=1,VerSum=6,Ver=6,T=4,value=497655],
  [Packet:LVL=1,VerSum=13,Ver=7,T=2,value=
    [Packet:LVL=2,VerSum=6,Ver=6,T=4,value=3]],
  [Packet:LVL=1,VerSum=4,Ver=4,T=4,value=42002],
  [Packet:LVL=1,VerSum=43,Ver=1,T=1,value=
    [Packet:LVL=2,VerSum=3,Ver=3,T=4,value=18874],
    [Packet:LVL=2,VerSum=39,Ver=3,T=5,value=
      [Packet:LVL=3,VerSum=14,Ver=3,T=0,value=
        [Packet:LVL=4,VerSum=7,Ver=7,T=4,value=12],
        [Packet:LVL=4,VerSum=4,Ver=4,T=4,value=5],
        [Packet:LVL=4,VerSum=0,Ver=0,T=4,value=12]],
      [Packet:LVL=3,VerSum=22,Ver=7,T=0,value=
        [Packet:LVL=4,VerSum=2,Ver=2,T=4,value=8],
        [Packet:LVL=4,VerSum=7,Ver=7,T=4,value=6],
        [Packet:LVL=4,VerSum=6,Ver=6,T=4,value=11]]]],
  [Packet:LVL=1,VerSum=3,Ver=3,T=4,value=9],
  [Packet:LVL=1,VerSum=22,Ver=7,T=1,value=
    [Packet:LVL=2,VerSum=14,Ver=5,T=7,value=
      [Packet:LVL=3,VerSum=4,Ver=4,T=4,value=35175563],
      [Packet:LVL=3,VerSum=5,Ver=5,T=4,value=133]],
    [Packet:LVL=2,VerSum=1,Ver=1,T=4,value=3584]],
  [Packet:LVL=1,VerSum=16,Ver=1,T=1,value=
    [Packet:LVL=2,VerSum=7,Ver=7,T=4,value=3683],
    [Packet:LVL=2,VerSum=8,Ver=1,T=6,value=
      [Packet:LVL=3,VerSum=4,Ver=4,T=4,value=248005212],
      [Packet:LVL=3,VerSum=3,Ver=3,T=4,value=248005212]]],
  [Packet:LVL=1,VerSum=52,Ver=6,T=1,value=
    [Packet:LVL=2,VerSum=12,Ver=4,T=0,value=
      [Packet:LVL=3,VerSum=6,Ver=6,T=4,value=15],
      [Packet:LVL=3,VerSum=2,Ver=2,T=4,value=4],
      [Packet:LVL=3,VerSum=0,Ver=0,T=4,value=11]],
    [Packet:LVL=2,VerSum=14,Ver=4,T=0,value=
      [Packet:LVL=3,VerSum=3,Ver=3,T=4,value=11],
      [Packet:LVL=3,VerSum=1,Ver=1,T=4,value=12],
      [Packet:LVL=3,VerSum=6,Ver=6,T=4,value=14]],
    [Packet:LVL=2,VerSum=20,Ver=6,T=0,value=
      [Packet:LVL=3,VerSum=6,Ver=6,T=4,value=10],
      [Packet:LVL=3,VerSum=6,Ver=6,T=4,value=10],
      [Packet:LVL=3,VerSum=2,Ver=2,T=4,value=8]]],
  [Packet:LVL=1,VerSum=16,Ver=1,T=1,value=
    [Packet:LVL=2,VerSum=13,Ver=7,T=6,value=
      [Packet:LVL=3,VerSum=2,Ver=2,T=4,value=1217],
      [Packet:LVL=3,VerSum=4,Ver=4,T=4,value=151]],
    [Packet:LVL=2,VerSum=2,Ver=2,T=4,value=588931]],
  [Packet:LVL=1,VerSum=7,Ver=7,T=4,value=4],
  [Packet:LVL=1,VerSum=20,Ver=3,T=0,value=
    [Packet:LVL=2,VerSum=5,Ver=5,T=4,value=48],
    [Packet:LVL=2,VerSum=7,Ver=7,T=4,value=45472],
    [Packet:LVL=2,VerSum=5,Ver=5,T=4,value=94453890]],
  [Packet:LVL=1,VerSum=48,Ver=4,T=0,value=
    [Packet:LVL=2,VerSum=15,Ver=6,T=1,value=
      [Packet:LVL=3,VerSum=2,Ver=2,T=4,value=7],
      [Packet:LVL=3,VerSum=4,Ver=4,T=4,value=12],
      [Packet:LVL=3,VerSum=3,Ver=3,T=4,value=5]],
    [Packet:LVL=2,VerSum=16,Ver=4,T=1,value=
      [Packet:LVL=3,VerSum=6,Ver=6,T=4,value=13],
      [Packet:LVL=3,VerSum=5,Ver=5,T=4,value=5],
      [Packet:LVL=3,VerSum=1,Ver=1,T=4,value=15]],
    [Packet:LVL=2,VerSum=13,Ver=0,T=1,value=
      [Packet:LVL=3,VerSum=1,Ver=1,T=4,value=7],
      [Packet:LVL=3,VerSum=5,Ver=5,T=4,value=13],
      [Packet:LVL=3,VerSum=7,Ver=7,T=4,value=9]]],
  [Packet:LVL=1,VerSum=4,Ver=2,T=1,value=
    [Packet:LVL=2,VerSum=0,Ver=0,T=4,value=164],
    [Packet:LVL=2,VerSum=2,Ver=2,T=4,value=165]],
  [Packet:LVL=1,VerSum=18,Ver=6,T=1,value=
    [Packet:LVL=2,VerSum=6,Ver=6,T=4,value=59825],
    [Packet:LVL=2,VerSum=6,Ver=3,T=5,value=
      [Packet:LVL=3,VerSum=2,Ver=2,T=4,value=3724],
      [Packet:LVL=3,VerSum=1,Ver=1,T=4,value=956760]]],
  [Packet:LVL=1,VerSum=80,Ver=7,T=0,value=
    [Packet:LVL=2,VerSum=73,Ver=4,T=3,value=
      [Packet:LVL=3,VerSum=69,Ver=0,T=3,value=
        [Packet:LVL=4,VerSum=69,Ver=6,T=1,value=
          [Packet:LVL=5,VerSum=63,Ver=1,T=1,value=
            [Packet:LVL=6,VerSum=62,Ver=1,T=1,value=
              [Packet:LVL=7,VerSum=61,Ver=3,T=3,value=
                [Packet:LVL=8,VerSum=58,Ver=6,T=3,value=
                  [Packet:LVL=9,VerSum=52,Ver=6,T=0,value=
                    [Packet:LVL=10,VerSum=46,Ver=0,T=1,value=
                      [Packet:LVL=11,VerSum=46,Ver=2,T=0,value=
                        [Packet:LVL=12,VerSum=44,Ver=2,T=0,value=
                          [Packet:LVL=13,VerSum=42,Ver=7,T=2,value=
                            [Packet:LVL=14,VerSum=35,Ver=5,T=2,value=
                              [Packet:LVL=15,VerSum=30,Ver=4,T=2,value=
                                [Packet:LVL=16,VerSum=26,Ver=6,T=0,value=
                                  [Packet:LVL=17,VerSum=20,Ver=4,T=0,value=
                                    [Packet:LVL=18,VerSum=16,Ver=4,T=2,value=
                                      [Packet:LVL=19,VerSum=12,Ver=1,T=2,value=
                                        [Packet:LVL=20,VerSum=11,Ver=4,T=2,value=
                                          [Packet:LVL=21,VerSum=7,Ver=7,T=4,value=3547]]]]]]]]]]]]]]]]]]]]],
  [Packet:LVL=1,VerSum=9,Ver=0,T=0,value=
    [Packet:LVL=2,VerSum=6,Ver=6,T=4,value=2],
    [Packet:LVL=2,VerSum=3,Ver=3,T=4,value=101374]],
  [Packet:LVL=1,VerSum=33,Ver=3,T=1,value=
    [Packet:LVL=2,VerSum=3,Ver=3,T=4,value=2788],
    [Packet:LVL=2,VerSum=27,Ver=6,T=5,value=
      [Packet:LVL=3,VerSum=12,Ver=2,T=0,value=
        [Packet:LVL=4,VerSum=7,Ver=7,T=4,value=6],
        [Packet:LVL=4,VerSum=2,Ver=2,T=4,value=9],
        [Packet:LVL=4,VerSum=1,Ver=1,T=4,value=9]],
      [Packet:LVL=3,VerSum=9,Ver=0,T=0,value=
        [Packet:LVL=4,VerSum=4,Ver=4,T=4,value=13],
        [Packet:LVL=4,VerSum=4,Ver=4,T=4,value=2],
        [Packet:LVL=4,VerSum=1,Ver=1,T=4,value=15]]]],
  [Packet:LVL=1,VerSum=18,Ver=4,T=2,value=
    [Packet:LVL=2,VerSum=0,Ver=0,T=4,value=3685],
    [Packet:LVL=2,VerSum=1,Ver=1,T=4,value=7582],
    [Packet:LVL=2,VerSum=2,Ver=2,T=4,value=81],
    [Packet:LVL=2,VerSum=6,Ver=6,T=4,value=701716],
    [Packet:LVL=2,VerSum=5,Ver=5,T=4,value=429274]],
  [Packet:LVL=1,VerSum=34,Ver=0,T=1,value=
    [Packet:LVL=2,VerSum=30,Ver=3,T=6,value=
      [Packet:LVL=3,VerSum=12,Ver=3,T=0,value=
        [Packet:LVL=4,VerSum=1,Ver=1,T=4,value=11],
        [Packet:LVL=4,VerSum=7,Ver=7,T=4,value=9],
        [Packet:LVL=4,VerSum=1,Ver=1,T=4,value=10]],
      [Packet:LVL=3,VerSum=15,Ver=5,T=0,value=
        [Packet:LVL=4,VerSum=1,Ver=1,T=4,value=12],
        [Packet:LVL=4,VerSum=4,Ver=4,T=4,value=5],
        [Packet:LVL=4,VerSum=5,Ver=5,T=4,value=14]]],
    [Packet:LVL=2,VerSum=4,Ver=4,T=4,value=66]],
  [Packet:LVL=1,VerSum=14,Ver=1,T=1,value=
    [Packet:LVL=2,VerSum=3,Ver=3,T=4,value=158],
    [Packet:LVL=2,VerSum=10,Ver=5,T=6,value=
      [Packet:LVL=3,VerSum=2,Ver=2,T=4,value=123061340],
      [Packet:LVL=3,VerSum=3,Ver=3,T=4,value=309]]],
  [Packet:LVL=1,VerSum=2,Ver=1,T=2,value=
    [Packet:LVL=2,VerSum=1,Ver=1,T=4,value=265210578],
    [Packet:LVL=2,VerSum=0,Ver=0,T=4,value=10]],
  [Packet:LVL=1,VerSum=7,Ver=7,T=4,value=31918501],
  [Packet:LVL=1,VerSum=28,Ver=4,T=1,value=
    [Packet:LVL=2,VerSum=4,Ver=4,T=4,value=205],
    [Packet:LVL=2,VerSum=2,Ver=2,T=4,value=109],
    [Packet:LVL=2,VerSum=5,Ver=5,T=4,value=187],
    [Packet:LVL=2,VerSum=7,Ver=7,T=4,value=92],
    [Packet:LVL=2,VerSum=6,Ver=6,T=4,value=159]],
  [Packet:LVL=1,VerSum=13,Ver=0,T=2,value=
    [Packet:LVL=2,VerSum=7,Ver=7,T=4,value=29305],
    [Packet:LVL=2,VerSum=3,Ver=3,T=4,value=2195],
    [Packet:LVL=2,VerSum=3,Ver=3,T=4,value=98863220],
    [Packet:LVL=2,VerSum=0,Ver=0,T=4,value=15518495373]],
  [Packet:LVL=1,VerSum=22,Ver=3,T=1,value=
    [Packet:LVL=2,VerSum=12,Ver=5,T=5,value=
      [Packet:LVL=3,VerSum=6,Ver=6,T=4,value=491281],
      [Packet:LVL=3,VerSum=1,Ver=1,T=4,value=491281]],
    [Packet:LVL=2,VerSum=7,Ver=7,T=4,value=49105]],
  [Packet:LVL=1,VerSum=22,Ver=6,T=1,value=
    [Packet:LVL=2,VerSum=11,Ver=4,T=5,value=
      [Packet:LVL=3,VerSum=5,Ver=5,T=4,value=3696],
      [Packet:LVL=3,VerSum=2,Ver=2,T=4,value=81611779]],
    [Packet:LVL=2,VerSum=5,Ver=5,T=4,value=51781]],
  [Packet:LVL=1,VerSum=5,Ver=5,T=3,value=
    [Packet:LVL=2,VerSum=0,Ver=0,T=4,value=11],
    [Packet:LVL=2,VerSum=0,Ver=0,T=4,value=14349575]]]

21 levels deep!!

TFTO.