From 3b3a25b9cd6ffcc422e10b51ef8e20f2aac9fb3e Mon Sep 17 00:00:00 2001 From: Josh Creek Date: Thu, 16 Dec 2021 18:28:43 +0000 Subject: [PATCH] refactor(*): Update 2021-16 part 1 files not working --- 2021/16/Program.cs | 90 +++++++++++++++++++++++++++++++++------------- 1 file changed, 65 insertions(+), 25 deletions(-) diff --git a/2021/16/Program.cs b/2021/16/Program.cs index 36f0cca..cee45d8 100644 --- a/2021/16/Program.cs +++ b/2021/16/Program.cs @@ -17,26 +17,41 @@ namespace Day16 static void Part1(string[] lines) { string hex = lines[0]; - string binary = Convert.ToString(Convert.ToInt32(hex, 16), 2); + Queue bitQueue = new Queue(); + + for (int i = 0; i < hex.Length; i++) + { + // Convert each hex character into binary + string currentHexCharacter = Convert.ToString(Convert.ToInt32(hex[i].ToString(), 16), 2); + + // Store each bit into the list + for (int j = 0; j < currentHexCharacter.Length; j++) + { + bitQueue.Enqueue(int.Parse(currentHexCharacter[j].ToString())); + } + } List versionNumbers = new List(); List outputList = new List(); - HandlePacket(ref versionNumbers, ref outputList, binary); + HandlePacket(ref versionNumbers, ref outputList, bitQueue); + + foreach (var item in versionNumbers) + { + Console.WriteLine(item); + } 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) + static void HandlePacket(ref List versionNumbers, ref List outputList, Queue bitQueue) { - int packetVersion = Convert.ToInt32(binary.Substring(0, 3), 2); + int packetVersion = Convert.ToInt32($"{bitQueue.Dequeue()}{bitQueue.Dequeue()}{bitQueue.Dequeue()}", 2); versionNumbers.Add(packetVersion); - int typeId = Convert.ToInt32(binary.Substring(3, 3), 2); - - string remainingBinary = binary.Substring(6, binary.Length - 6); + int typeId = Convert.ToInt32($"{bitQueue.Dequeue()}{bitQueue.Dequeue()}{bitQueue.Dequeue()}", 2); if (typeId == 4) { @@ -48,17 +63,18 @@ namespace Day16 * 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; + bool isEndOfPacket = false; - for (int i = 0; i < remainingBinary.Length; i += 5) + while (!isEndOfPacket) { - binaryLiteral.Append(remainingBinary.Substring(i + 1, 4)); + int endOfPacketIdentifier = bitQueue.Dequeue(); - if (remainingBinary[i] == '0') + binaryLiteral.Append($"{bitQueue.Dequeue()}{bitQueue.Dequeue()}{bitQueue.Dequeue()}{bitQueue.Dequeue()}"); + + if (endOfPacketIdentifier == 0) { // last group, end of packet - unprocessedBinary = remainingBinary.Substring(i + 5, remainingBinary.Length - i); - break; + isEndOfPacket = true; } } @@ -68,39 +84,63 @@ namespace Day16 outputList.Add(output); // if the unprocessed binary doesn't just contain zeros process it again - if (!Regex.IsMatch(unprocessedBinary, @"^(0+)$")) + if (bitQueue.Count >= 11 && bitQueue.Any(b => (b != 0))) { - HandlePacket(ref versionNumbers, ref outputList, unprocessedBinary); + HandlePacket(ref versionNumbers, ref outputList, bitQueue); } } else { // Packets represent an operator - char lengthTypeId = remainingBinary[0]; + int lengthTypeId = bitQueue.Dequeue(); - if (lengthTypeId == '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); + StringBuilder sb = new StringBuilder(); - string binaryToStillProcess = remainingBinary.Substring(16, totalLengthInBitsOfSubPacketsContainedByThisPacket); + for (int i = 0; i < 15 && bitQueue.Count > 0; i++) + { + sb.Append(bitQueue.Dequeue()); + } - HandlePacket(ref versionNumbers, ref outputList, binaryToStillProcess); + int totalLengthInBitsOfSubPacketsContainedByThisPacket = Convert.ToInt32(sb.ToString(), 2); + + + Queue newBitQueue = new Queue(); + + for (int i = 0; i < totalLengthInBitsOfSubPacketsContainedByThisPacket && bitQueue.Count > 0; i++) + { + newBitQueue.Enqueue(bitQueue.Dequeue()); + } + + if (bitQueue.Count >= 11) + { + HandlePacket(ref versionNumbers, ref outputList, newBitQueue); + } } - else if (lengthTypeId == '1') + 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); + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < 11 && bitQueue.Count > 0; i++) + { + sb.Append(bitQueue.Dequeue()); + } + + int numberOfSubPacketsImmediatelyContainedByThisPacket = Convert.ToInt32(sb.ToString(), 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); + if (bitQueue.Count >= 11) + { + HandlePacket(ref versionNumbers, ref outputList, bitQueue); + } } } }