Day 16, extreme parsing edition
This commit is contained in:
@ -63,6 +63,9 @@
|
||||
<None Update="inputs\15.txt">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="inputs\16.txt">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
1
inputs/16.txt
Normal file
1
inputs/16.txt
Normal file
@ -0,0 +1 @@
|
||||
A20D5080210CE4BB9BAFB001BD14A4574C014C004AE46A9B2E27297EECF0C013F00564776D7E3A825CAB8CD47B6C537DB99CD746674C1000D29BBC5AC80442966FB004C401F8771B61D8803D0B22E4682010EE7E59ACE5BC086003E3270AE4024E15C8010073B2FAD98E004333F9957BCB602E7024C01197AD452C01295CE2DC9934928B005DD258A6637F534CB3D89A944230043801A596B234B7E58509E88798029600BCF5B3BA114F5B3BA10C9E77BAF20FA4016FCDD13340118B929DD4FD54E60327C00BEB7002080AA850031400D002369400B10034400F30021400F20157D804AD400FE00034E000A6D001EB2004E5C00B9AE3AC3C300470029091ACADBFA048D656DFD126792187008635CD736B3231A51BA5EBDF42D4D299804F26B33C872E213C840022EC9C21FFB34EDE7C559C8964B43F8AD77570200FC66697AFEB6C757AC0179AB641E6AD9022006065CEA714A4D24C0179F8E795D3078026200FC118EB1B40010A8D11EA27100990200C45A83F12C401A8611D60A0803B1723542889537EFB24D6E0844004248B1980292D608D00423F49F9908049798B4452C0131006230C14868200FC668B50650043196A7F95569CF6B663341535DCFE919C464400A96DCE1C6B96D5EEFE60096006A400087C1E8610A4401887D1863AC99F9802DC00D34B5BCD72D6F36CB6E7D95EBC600013A88010A8271B6281803B12E124633006A2AC3A8AC600BCD07C9851008712DEAE83A802929DC51EE5EF5AE61BCD0648028596129C3B98129E5A9A329ADD62CCE0164DDF2F9343135CCE2137094A620E53FACF37299F0007392A0B2A7F0BA5F61B3349F3DFAEDE8C01797BD3F8BC48740140004322246A8A2200CC678651AA46F09AEB80191940029A9A9546E79764F7C9D608EA0174B63F815922999A84CE7F95C954D7FD9E0890047D2DC13B0042488259F4C0159922B0046565833828A00ACCD63D189D4983E800AFC955F211C700
|
165
src/16.cs
Normal file
165
src/16.cs
Normal file
@ -0,0 +1,165 @@
|
||||
using System.Text;
|
||||
|
||||
namespace aoc2021;
|
||||
|
||||
internal class Day16 : Day
|
||||
{
|
||||
internal override void Go()
|
||||
{
|
||||
var lines = Util.ReadAllLines("inputs/16.txt");
|
||||
var input = lines.ElementAt(0);
|
||||
var binStr = string.Empty;
|
||||
foreach (var ch in input)
|
||||
{
|
||||
binStr += Convert.ToString(Convert.ToInt64(ch.ToString(), 16), 2).PadLeft(4, '0');
|
||||
}
|
||||
int idx = 0;
|
||||
using var t = new Timer("Decoding packet");
|
||||
(var versionTotal, var result) = DecodePacket(binStr, ref idx);
|
||||
t.Stop();
|
||||
Part1(versionTotal);
|
||||
Part2(result);
|
||||
}
|
||||
|
||||
private static void Part1(long versionTotal)
|
||||
{
|
||||
Logger.Log($"part1: version total: <blue>{versionTotal}<r>");
|
||||
}
|
||||
|
||||
private static void Part2(long result)
|
||||
{
|
||||
Logger.Log($"part2: operator result: <blue>{result}<r>");
|
||||
}
|
||||
|
||||
private static (long versionTotal, long result) DecodePacket(string binary, ref int idx)
|
||||
{
|
||||
long versionTotal = 0;
|
||||
|
||||
(var version, var typeID) = ParsePacketHeader(binary, ref idx);
|
||||
versionTotal += version;
|
||||
long result;
|
||||
switch (typeID)
|
||||
{
|
||||
case 4:
|
||||
result = ParseLiteralPacket(binary, ref idx);
|
||||
break;
|
||||
|
||||
default:
|
||||
(version, result) = ParseOperatorPacket(binary, typeID, ref idx);
|
||||
versionTotal += version;
|
||||
break;
|
||||
}
|
||||
|
||||
return (versionTotal, result);
|
||||
}
|
||||
|
||||
private static (long, long) ParsePacketHeader(string binary, ref int idx)
|
||||
{
|
||||
var version = Convert.ToInt64(binary[idx..(idx + 3)], 2);
|
||||
idx += 3;
|
||||
var typeID = Convert.ToInt64(binary[idx..(idx + 3)], 2);
|
||||
idx += 3;
|
||||
return (version, typeID);
|
||||
}
|
||||
|
||||
private static long ParseLiteralPacket(string binary, ref int idx)
|
||||
{
|
||||
StringBuilder numStr = new();
|
||||
bool done = false;
|
||||
while (!done)
|
||||
{
|
||||
if (binary[idx] == '0')
|
||||
{
|
||||
done = true;
|
||||
}
|
||||
|
||||
numStr.Append(binary[(idx + 1)..(idx + 5)]);
|
||||
idx += 5;
|
||||
}
|
||||
|
||||
return Convert.ToInt64(numStr.ToString(), 2);
|
||||
}
|
||||
|
||||
private static (long versionTotal, long result) ParseOperatorPacket(string binary, long inType, ref int idx)
|
||||
{
|
||||
var lengthType = Convert.ToInt64(binary[idx..(idx + 1)], 2);
|
||||
idx++;
|
||||
|
||||
long totalLength = 0;
|
||||
long numSubPackets = 0;
|
||||
switch (lengthType)
|
||||
{
|
||||
case 0:
|
||||
totalLength = Convert.ToInt64(binary[idx..(idx + 15)], 2);
|
||||
idx += 15;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
numSubPackets = Convert.ToInt64(binary[idx..(idx + 11)], 2);
|
||||
idx += 11;
|
||||
break;
|
||||
}
|
||||
|
||||
long versionTotal = 0;
|
||||
|
||||
bool done = false;
|
||||
int startIdx = idx;
|
||||
long lengthProcessed = 0;
|
||||
long subPacketsProcessed = 0;
|
||||
List<long> operands = new();
|
||||
while (!done)
|
||||
{
|
||||
(var version, var operand) = DecodePacket(binary, ref idx);
|
||||
operands.Add(operand);
|
||||
subPacketsProcessed++;
|
||||
lengthProcessed = idx - startIdx;
|
||||
versionTotal += version;
|
||||
|
||||
done = done || (numSubPackets != 0 && subPacketsProcessed == numSubPackets);
|
||||
done = done || (totalLength != 0 && lengthProcessed == totalLength);
|
||||
}
|
||||
|
||||
long result = 0;
|
||||
switch (inType)
|
||||
{
|
||||
case 0:
|
||||
result = operands.Sum(x => x);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
result = operands.Aggregate(1L, (agg, x) => x * agg);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
result = operands.Min(x => x);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
result = operands.Max(x => x);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
throw new Exception();
|
||||
|
||||
case 5:
|
||||
System.Diagnostics.Debug.Assert(operands.Count == 2);
|
||||
result = operands[0] > operands[1] ? 1 : 0;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
System.Diagnostics.Debug.Assert(operands.Count == 2);
|
||||
result = operands[0] < operands[1] ? 1 : 0;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
System.Diagnostics.Debug.Assert(operands.Count == 2);
|
||||
result = operands[0] == operands[1] ? 1 : 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
return (versionTotal, result);
|
||||
}
|
||||
}
|
@ -33,7 +33,8 @@ else
|
||||
"12" => new Day12(),
|
||||
"13" => new Day13(),
|
||||
"14" => new Day14(),
|
||||
_ => new Day15(),
|
||||
"15" => new Day15(),
|
||||
_ => new Day16(),
|
||||
};
|
||||
day.Go();
|
||||
}
|
||||
|
Reference in New Issue
Block a user