From bef3eb551ba03dbdd3d05782cdeddf051e25b5c5 Mon Sep 17 00:00:00 2001 From: Josh Creek Date: Thu, 16 Dec 2021 09:32:14 +0000 Subject: [PATCH] feat(*): Add 2021-16 part 1 files not working --- 2021/16/16.csproj | 17 +++++++ 2021/16/Program.cs | 108 ++++++++++++++++++++++++++++++++++++++++++ 2021/16/TaskPart1.txt | 83 ++++++++++++++++++++++++++++++++ 2021/AOC2021.sln | 14 +++++- 4 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 2021/16/16.csproj create mode 100644 2021/16/Program.cs create mode 100644 2021/16/TaskPart1.txt 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