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
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user