private static long ProcessPacket(BinaryString b, List <long> versions) { long version = b.ReadBits(3); long type = b.ReadBits(3); versions.Add(version); if (type == 4) { // Base case. Literals contain no sub packets, so just calculate the value they represent and return return(ProcessLiteral(b)); } List <long> subResults = new(); // Operator case. Determine how to read the sub packets long lengthTypeId = b.ReadBits(1); if (lengthTypeId == 0) { // Sub packet section is defined by the number of bits long subPacketBitLength = b.ReadBits(15); long positionBefore = b.Position; long goalPosition = positionBefore + subPacketBitLength; while (b.Position < goalPosition) { long subResult = ProcessPacket(b, versions); subResults.Add(subResult); } } else if (lengthTypeId == 1) { // Sub packet section is defined by the number of packets long numberOfSubPackets = b.ReadBits(11); for (int i = 0; i < numberOfSubPackets; i++) { long subResult = ProcessPacket(b, versions); subResults.Add(subResult); } } // Evaluate the different operators against the sub packet results return(type switch { 0 => subResults.Sum(), 1 => subResults.Aggregate(1L, (acc, x) => acc * x), 2 => subResults.Min(), 3 => subResults.Max(), 5 => subResults[0] > subResults[1] ? 1 : 0, 6 => subResults[0] < subResults[1] ? 1 : 0, 7 => subResults[0] == subResults[1] ? 1 : 0, _ => throw new NotSupportedException(type.ToString()), });