Day 16, extreme parsing edition

This commit is contained in:
2021-12-16 09:23:08 -06:00
parent eeed2bbdd3
commit 542df5bd8c
4 changed files with 171 additions and 1 deletions

View File

@ -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
View File

@ -0,0 +1 @@
A20D5080210CE4BB9BAFB001BD14A4574C014C004AE46A9B2E27297EECF0C013F00564776D7E3A825CAB8CD47B6C537DB99CD746674C1000D29BBC5AC80442966FB004C401F8771B61D8803D0B22E4682010EE7E59ACE5BC086003E3270AE4024E15C8010073B2FAD98E004333F9957BCB602E7024C01197AD452C01295CE2DC9934928B005DD258A6637F534CB3D89A944230043801A596B234B7E58509E88798029600BCF5B3BA114F5B3BA10C9E77BAF20FA4016FCDD13340118B929DD4FD54E60327C00BEB7002080AA850031400D002369400B10034400F30021400F20157D804AD400FE00034E000A6D001EB2004E5C00B9AE3AC3C300470029091ACADBFA048D656DFD126792187008635CD736B3231A51BA5EBDF42D4D299804F26B33C872E213C840022EC9C21FFB34EDE7C559C8964B43F8AD77570200FC66697AFEB6C757AC0179AB641E6AD9022006065CEA714A4D24C0179F8E795D3078026200FC118EB1B40010A8D11EA27100990200C45A83F12C401A8611D60A0803B1723542889537EFB24D6E0844004248B1980292D608D00423F49F9908049798B4452C0131006230C14868200FC668B50650043196A7F95569CF6B663341535DCFE919C464400A96DCE1C6B96D5EEFE60096006A400087C1E8610A4401887D1863AC99F9802DC00D34B5BCD72D6F36CB6E7D95EBC600013A88010A8271B6281803B12E124633006A2AC3A8AC600BCD07C9851008712DEAE83A802929DC51EE5EF5AE61BCD0648028596129C3B98129E5A9A329ADD62CCE0164DDF2F9343135CCE2137094A620E53FACF37299F0007392A0B2A7F0BA5F61B3349F3DFAEDE8C01797BD3F8BC48740140004322246A8A2200CC678651AA46F09AEB80191940029A9A9546E79764F7C9D608EA0174B63F815922999A84CE7F95C954D7FD9E0890047D2DC13B0042488259F4C0159922B0046565833828A00ACCD63D189D4983E800AFC955F211C700

165
src/16.cs Normal file
View 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);
}
}

View File

@ -33,7 +33,8 @@ else
"12" => new Day12(),
"13" => new Day13(),
"14" => new Day14(),
_ => new Day15(),
"15" => new Day15(),
_ => new Day16(),
};
day.Go();
}