mirror of
https://github.com/jcreek/advent-of-code.git
synced 2026-07-12 18:53:47 +00:00
feat(*): Add 2021-16 part 1 files not working
This commit is contained in:
@@ -0,0 +1,17 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<RootNamespace>_16</RootNamespace>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="input.txt">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -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<int> versionNumbers = new List<int>();
|
||||||
|
List<int> outputList = new List<int>();
|
||||||
|
|
||||||
|
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<int> versionNumbers, ref List<int> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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?
|
||||||
+13
-1
@@ -25,7 +25,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "10", "10\10.csproj", "{C930
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "11", "11\11.csproj", "{6F13298E-B8CA-4A67-B1E7-320B5637CE6A}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "11", "11\11.csproj", "{6F13298E-B8CA-4A67-B1E7-320B5637CE6A}"
|
||||||
EndProject
|
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
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
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}.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.ActiveCfg = Release|Any CPU
|
||||||
{9F9653A8-5A92-40C3-A855-7D0F0EAEC422}.Release|Any CPU.Build.0 = 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
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
Reference in New Issue
Block a user