diff --git a/2021/16/16.csproj b/2021/16/16.csproj
new file mode 100644
index 0000000..c0c1b96
--- /dev/null
+++ b/2021/16/16.csproj
@@ -0,0 +1,17 @@
+
+
+
+ Exe
+ net6.0
+ _16
+ enable
+ enable
+
+
+
+
+ PreserveNewest
+
+
+
+
diff --git a/2021/16/Program.cs b/2021/16/Program.cs
new file mode 100644
index 0000000..36f0cca
--- /dev/null
+++ b/2021/16/Program.cs
@@ -0,0 +1,108 @@
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace Day16
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ string[] lines = File.ReadAllLines("input.txt");
+
+
+ Part1(lines);
+ //Part2(lines);
+ }
+
+ static void Part1(string[] lines)
+ {
+ string hex = lines[0];
+ string binary = Convert.ToString(Convert.ToInt32(hex, 16), 2);
+
+ List versionNumbers = new List();
+ List outputList = new List();
+
+ HandlePacket(ref versionNumbers, ref outputList, binary);
+
+ int total = versionNumbers.Sum(x => x);
+
+ Console.WriteLine($"The sum of version numbers in all packets is: {total}");
+ }
+
+ static void HandlePacket(ref List versionNumbers, ref List outputList, string binary)
+ {
+ int packetVersion = Convert.ToInt32(binary.Substring(0, 3), 2);
+ versionNumbers.Add(packetVersion);
+
+ int typeId = Convert.ToInt32(binary.Substring(3, 3), 2);
+
+ string remainingBinary = binary.Substring(6, binary.Length - 6);
+
+ if (typeId == 4)
+ {
+ // Packets represent a literal value
+ /*
+ * Literal value packets encode a single binary number. To do this, the binary number
+ * is padded with leading zeroes until its length is a multiple of four bits, and then
+ * it is broken into groups of four bits. Each group is prefixed by a 1 bit except the last
+ * group, which is prefixed by a 0 bit. These groups of five bits immediately follow the packet header.
+ */
+ StringBuilder binaryLiteral = new StringBuilder();
+ string unprocessedBinary = string.Empty;
+
+ for (int i = 0; i < remainingBinary.Length; i += 5)
+ {
+ binaryLiteral.Append(remainingBinary.Substring(i + 1, 4));
+
+ if (remainingBinary[i] == '0')
+ {
+ // last group, end of packet
+ unprocessedBinary = remainingBinary.Substring(i + 5, remainingBinary.Length - i);
+ break;
+ }
+ }
+
+ string binaryLiteralString = binaryLiteral.ToString();
+ int output = Convert.ToInt32(binaryLiteralString, 2);
+
+ outputList.Add(output);
+
+ // if the unprocessed binary doesn't just contain zeros process it again
+ if (!Regex.IsMatch(unprocessedBinary, @"^(0+)$"))
+ {
+ HandlePacket(ref versionNumbers, ref outputList, unprocessedBinary);
+ }
+ }
+ else
+ {
+ // Packets represent an operator
+ char lengthTypeId = remainingBinary[0];
+
+ if (lengthTypeId == '0')
+ {
+ // the next _15_ bits are a number that represents the _total length in bits_ of the
+ // sub-packets contained by this packet.
+
+ int totalLengthInBitsOfSubPacketsContainedByThisPacket = Convert.ToInt32(remainingBinary.Substring(1, 15), 2);
+
+ string binaryToStillProcess = remainingBinary.Substring(16, totalLengthInBitsOfSubPacketsContainedByThisPacket);
+
+ HandlePacket(ref versionNumbers, ref outputList, binaryToStillProcess);
+ }
+ else if (lengthTypeId == '1')
+ {
+ // the next _11_ bits are a number that represents the _number of sub-packets
+ // immediately contained_ by this packet.
+
+ int numberOfSubPacketsImmediatelyContainedByThisPacket = Convert.ToInt32(remainingBinary.Substring(1, 11), 2);
+
+ // TODO - I can't see how I can even use this information
+
+ string binaryToStillProcess = remainingBinary.Substring(16, remainingBinary.Length - 16);
+
+ HandlePacket(ref versionNumbers, ref outputList, binaryToStillProcess);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/2021/16/TaskPart1.txt b/2021/16/TaskPart1.txt
new file mode 100644
index 0000000..af379f5
--- /dev/null
+++ b/2021/16/TaskPart1.txt
@@ -0,0 +1,83 @@
+--- Day 16: Packet Decoder ---
+As you leave the cave and reach open waters, you receive a transmission from the Elves back on the ship.
+
+The transmission was sent using the Buoyancy Interchange Transmission System (BITS), a method of packing numeric expressions into a binary sequence. Your submarine's computer has saved the transmission in hexadecimal (your puzzle input).
+
+The first step of decoding the message is to convert the hexadecimal representation into binary. Each character of hexadecimal corresponds to four bits of binary data:
+
+0 = 0000
+1 = 0001
+2 = 0010
+3 = 0011
+4 = 0100
+5 = 0101
+6 = 0110
+7 = 0111
+8 = 1000
+9 = 1001
+A = 1010
+B = 1011
+C = 1100
+D = 1101
+E = 1110
+F = 1111
+The BITS transmission contains a single packet at its outermost layer which itself contains many other packets. The hexadecimal representation of this packet might encode a few extra 0 bits at the end; these are not part of the transmission and should be ignored.
+
+Every packet begins with a standard header: the first three bits encode the packet version, and the next three bits encode the packet type ID. These two values are numbers; all numbers encoded in any packet are represented as binary with the most significant bit first. For example, a version encoded as the binary sequence 100 represents the number 4.
+
+Packets with type ID 4 represent a literal value. Literal value packets encode a single binary number. To do this, the binary number is padded with leading zeroes until its length is a multiple of four bits, and then it is broken into groups of four bits. Each group is prefixed by a 1 bit except the last group, which is prefixed by a 0 bit. These groups of five bits immediately follow the packet header. For example, the hexadecimal string D2FE28 becomes:
+
+110100101111111000101000
+VVVTTTAAAAABBBBBCCCCC
+Below each bit is a label indicating its purpose:
+
+The three bits labeled V (110) are the packet version, 6.
+The three bits labeled T (100) are the packet type ID, 4, which means the packet is a literal value.
+The five bits labeled A (10111) start with a 1 (not the last group, keep reading) and contain the first four bits of the number, 0111.
+The five bits labeled B (11110) start with a 1 (not the last group, keep reading) and contain four more bits of the number, 1110.
+The five bits labeled C (00101) start with a 0 (last group, end of packet) and contain the last four bits of the number, 0101.
+The three unlabeled 0 bits at the end are extra due to the hexadecimal representation and should be ignored.
+So, this packet represents a literal value with binary representation 011111100101, which is 2021 in decimal.
+
+Every other type of packet (any packet with a type ID other than 4) represent an operator that performs some calculation on one or more sub-packets contained within. Right now, the specific operations aren't important; focus on parsing the hierarchy of sub-packets.
+
+An operator packet contains one or more packets. To indicate which subsequent binary data represents its sub-packets, an operator packet can use one of two modes indicated by the bit immediately after the packet header; this is called the length type ID:
+
+If the length type ID is 0, then the next 15 bits are a number that represents the total length in bits of the sub-packets contained by this packet.
+If the length type ID is 1, then the next 11 bits are a number that represents the number of sub-packets immediately contained by this packet.
+Finally, after the length type ID bit and the 15-bit or 11-bit field, the sub-packets appear.
+
+For example, here is an operator packet (hexadecimal string 38006F45291200) with length type ID 0 that contains two sub-packets:
+
+00111000000000000110111101000101001010010001001000000000
+VVVTTTILLLLLLLLLLLLLLLAAAAAAAAAAABBBBBBBBBBBBBBBB
+The three bits labeled V (001) are the packet version, 1.
+The three bits labeled T (110) are the packet type ID, 6, which means the packet is an operator.
+The bit labeled I (0) is the length type ID, which indicates that the length is a 15-bit number representing the number of bits in the sub-packets.
+The 15 bits labeled L (000000000011011) contain the length of the sub-packets in bits, 27.
+The 11 bits labeled A contain the first sub-packet, a literal value representing the number 10.
+The 16 bits labeled B contain the second sub-packet, a literal value representing the number 20.
+After reading 11 and 16 bits of sub-packet data, the total length indicated in L (27) is reached, and so parsing of this packet stops.
+
+As another example, here is an operator packet (hexadecimal string EE00D40C823060) with length type ID 1 that contains three sub-packets:
+
+11101110000000001101010000001100100000100011000001100000
+VVVTTTILLLLLLLLLLLAAAAAAAAAAABBBBBBBBBBBCCCCCCCCCCC
+The three bits labeled V (111) are the packet version, 7.
+The three bits labeled T (011) are the packet type ID, 3, which means the packet is an operator.
+The bit labeled I (1) is the length type ID, which indicates that the length is a 11-bit number representing the number of sub-packets.
+The 11 bits labeled L (00000000011) contain the number of sub-packets, 3.
+The 11 bits labeled A contain the first sub-packet, a literal value representing the number 1.
+The 11 bits labeled B contain the second sub-packet, a literal value representing the number 2.
+The 11 bits labeled C contain the third sub-packet, a literal value representing the number 3.
+After reading 3 complete sub-packets, the number of sub-packets indicated in L (3) is reached, and so parsing of this packet stops.
+
+For now, parse the hierarchy of the packets throughout the transmission and add up all of the version numbers.
+
+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.
+Decode the structure of your hexadecimal-encoded BITS transmission; what do you get if you add up the version numbers in all packets?
\ No newline at end of file
diff --git a/2021/AOC2021.sln b/2021/AOC2021.sln
index 8bae545..75b4528 100644
--- a/2021/AOC2021.sln
+++ b/2021/AOC2021.sln
@@ -25,7 +25,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "10", "10\10.csproj", "{C930
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "11", "11\11.csproj", "{6F13298E-B8CA-4A67-B1E7-320B5637CE6A}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "14", "14\14.csproj", "{9F9653A8-5A92-40C3-A855-7D0F0EAEC422}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "14", "14\14.csproj", "{9F9653A8-5A92-40C3-A855-7D0F0EAEC422}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "15", "15\15.csproj", "{55BCEE74-A9E1-4506-B068-B25E7B9EA6ED}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "16", "16\16.csproj", "{692919B1-7363-4E0C-83C7-8367F819FA4F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -81,6 +85,14 @@ Global
{9F9653A8-5A92-40C3-A855-7D0F0EAEC422}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9F9653A8-5A92-40C3-A855-7D0F0EAEC422}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9F9653A8-5A92-40C3-A855-7D0F0EAEC422}.Release|Any CPU.Build.0 = Release|Any CPU
+ {55BCEE74-A9E1-4506-B068-B25E7B9EA6ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {55BCEE74-A9E1-4506-B068-B25E7B9EA6ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {55BCEE74-A9E1-4506-B068-B25E7B9EA6ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {55BCEE74-A9E1-4506-B068-B25E7B9EA6ED}.Release|Any CPU.Build.0 = Release|Any CPU
+ {692919B1-7363-4E0C-83C7-8367F819FA4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {692919B1-7363-4E0C-83C7-8367F819FA4F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {692919B1-7363-4E0C-83C7-8367F819FA4F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {692919B1-7363-4E0C-83C7-8367F819FA4F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE