Learning Python with Advent of Code Walkthroughs

Dazbo's Advent of Code solutions, written in Python

Advent of Code 2021 - Day 16

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:

• `v` = 3 bit packet version
• `t` = 3 bit packet type ID
• `p` = a number of bits for a literal value (`l`) or an operator packet (`o`)
• `x` = a number of 0s, to pad out the remaining bits such that the overall length is a multiple of 4 (since the original stream came from a number of hex digits)

If a literal packet:

• It contains one or more five bit sequences, where each sequence starts with a 1, except the last, which starts with a 0.

If an operator packet:

• It contains one or more nested packets. These could themselves be literals, or operator packets.
• The operator packet either has a `length type ID` which is one of two types:
• If type `0`, then the next 15 bits indiate the overal length of all the subpackets in this operator.
• If type `1`, then the next 11 bits represent the number of subpackets immediately contained in this 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:

• Parse input and convert from hex to binary.
• Create outer Packet from this data.
• Process the input bits according to the rules, and track how many bits have been used so far.
• Each `Packet` holds a `list` of subpackets. Track the depth of subpackets.
• When creating subpackets, consume bits as needed to create the subpackets, and then pass the remaining bits to the next.
• We want the sum of version numbers of all packets. Subpackets have version numbers, so we need to recursively add them.

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:

• Create a `list` of `outer_packets_data`, by reading each line of input, and converting each line from hex to binary.
• Our `hex_to_bin()` method converts all the hex digits to binary digits.
• Since every hex digit represents 4 binary digits, we know that the final binary stream length must be a multiple of 4.
• If you don’t understand this, I’d recommend brushing up on your base-2 and base-16 before continuing.
• We need to know the length of the binary representation of the hex string, because if we don’t, we’ll lose the leading zeroes. (As an analogy, consider that the decimal number 123 could actually be written 0123, or 00123, etc. And if the leading zeroes are important - as they are here - then we need to know how many there are!)
• The function first converts from hex to decimal, using `int(value, base)`, where `base=16`.
• It then converts the decimal number to binary, by applying a `format spec`, where:
• `{0}` is the first parameter to the `format()` method, i.e. the decimal value;
• And `:0{width}b` tells `format()` to convert to `binary` type, and then pad with `0` in order to achieve the desired `str` length.
• Each item in the `list` is an outer packet, so we construct a `Packet` from each item.

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:

• The `Packet` class has some class constants which are used to determine which bits are used for slicing the data, in order to obtain version, type, and value components of the `Packet`. Each outer `Packet` is created from the entire binary line. The outer packets have `level` set to the default of `0`.
• We store the binary data read as `_bin_in_str`.
• The `Packet` has a variable called `_sub_packets`, for storing a `list` of subpackets, if there are any.
• Now we read the the first three bits, to obtain the `_version`. We increment `_processed_bin_digits`, i.e. to reflect that we’ve read these 3 bits.
• Now we run the `_process_type()` method, which:
• Reads the next three bits, to determine the type. Again, increment `_processed_bin_digits` accordingly.
• If a literal packet, we run `_process_literal()`.
• Otherwise, we run `_process_operator()`.
• The `_process_literal()` method reads the subsequent groups, as required, and updates the `Packet's _literal_val` accordingly.
• The `_process_operator()` method is more complex. This method:
• Determines the length type.
• If length type is 0: create subpackets by reading in bits, until the specified number of bits have been read.
• If length type is 1: create the required number of subpackets from the stream.
• Update the `_processed_bin_digits` value.
• Finally, update the `Packet's _bin_in_self` value, such that it is the number of bits that was read to create this packet, including its subpackets.

Other methods worth mentioning:

• The `value` property simply returns `_literal_val`.
• The `version_sum` property is a simple recursive function that returns the current packet’s `version` value, add adds the sum of the `version` values of any subpackets. Obviously, this function will recurse for as long as there are packets with subpackets.

And finally, a note on representing the object:

• I’ve overridden two methods.
• The `__str__()` method provides a simple representation of the `Packet` object. It only shows the outer packet informatino, i.e.
• The `level` of `this packet`, where 0 is for the outermost packets.
• The (recursive) sum of version numbers.
• The `version` of `this packet`.
• The `type` of `this packet`.
• The `value` (i.e. `_literal_val`) of `this packet`.
• The hex representation of the bits that make up this outer packet; if the hex value is more than 10 characters, it shows only the first 10.
• The `__repr__()` method, which provides a more detailed recursive view of the `Packet` object, and all nested packets.
• It joins subpackets at the same level with `,`.
• It indents one extra level, for each level of subpacket nesting. This is achieved by simply multiplying two spaces by the nesting level, i.e. `" " * self._level`.

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.