day 16
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
feeling glad for Enumerable.Chunk today so i didn't have to write my own
This commit is contained in:
parent
3e5a5dc92b
commit
bf8e77441b
|
@ -36,6 +36,7 @@ public class DayTests
|
|||
[DataRow(typeof(Day13), "837", Day13Actual)]
|
||||
[DataRow(typeof(Day14), "5656", "12271437788530")]
|
||||
[DataRow(typeof(Day15), "702", "2955")]
|
||||
[DataRow(typeof(Day16), "852", "19348959966392")]
|
||||
public void CheckAllDays(Type dayType, string part1, string part2)
|
||||
{
|
||||
var s = Stopwatch.StartNew();
|
||||
|
@ -81,6 +82,7 @@ public class DayTests
|
|||
[DataRow(typeof(Day13), "17", Day13Test)]
|
||||
[DataRow(typeof(Day14), "1588", "2188189693529")]
|
||||
[DataRow(typeof(Day15), "40", "315")]
|
||||
[DataRow(typeof(Day16), "16", "15")]
|
||||
public void CheckTestInputs(Type dayType, string part1, string part2)
|
||||
{
|
||||
Day.UseTestInput = true;
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
namespace aoc2021;
|
||||
|
||||
/// <summary>
|
||||
/// Day 16: <see href="https://adventofcode.com/2021/day/16"/>
|
||||
/// </summary>
|
||||
public sealed class Day16 : Day
|
||||
{
|
||||
private readonly Packet _packet;
|
||||
|
||||
public Day16() : base(16, "Packet Decoder")
|
||||
{
|
||||
var bits = string.Join(string.Empty,
|
||||
Input.First().Select(c => Convert.ToString(Convert.ToInt32(c.ToString(), 16), 2).PadLeft(4, '0')));
|
||||
(_packet, _) = Packet.FromBinaryString(bits);
|
||||
}
|
||||
|
||||
private record Packet(int Version, int TypeId, long Value, List<Packet> Packets)
|
||||
{
|
||||
public static (Packet packet, int offset) FromBinaryString(string input)
|
||||
{
|
||||
var index = 0;
|
||||
var subPackets = new List<Packet>();
|
||||
var version = Convert.ToInt32(input[..(index += 3)], 2);
|
||||
var typeId = Convert.ToInt32(input[index..(index += 3)], 2);
|
||||
|
||||
if (typeId == 4)
|
||||
{
|
||||
// value packet, gather value bits and return right away
|
||||
var literalBits = new StringBuilder();
|
||||
foreach (var chunk in input.Skip(index).Chunk(5))
|
||||
{
|
||||
literalBits.Append(chunk[1..5]);
|
||||
index += 5;
|
||||
if (chunk[0] == '0') break;
|
||||
}
|
||||
|
||||
return (new(version, typeId, Convert.ToInt64(literalBits.ToString(), 2), new()), index);
|
||||
}
|
||||
|
||||
switch (input[index++])
|
||||
{
|
||||
case '0':
|
||||
var subPacketLength = Convert.ToInt32(input[index..(index += 15)], 2);
|
||||
while (subPacketLength > 0)
|
||||
{
|
||||
var (packet, offset) = FromBinaryString(input[index..(index + subPacketLength)]);
|
||||
subPackets.Add(packet);
|
||||
subPacketLength -= offset;
|
||||
index += offset;
|
||||
}
|
||||
|
||||
break;
|
||||
case '1':
|
||||
foreach (var _ in Enumerable.Range(0, Convert.ToInt32(input[index..(index += 11)], 2)))
|
||||
{
|
||||
var (packet, offset) = FromBinaryString(input[index..]);
|
||||
subPackets.Add(packet);
|
||||
index += offset;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return (new(version, typeId, 0, subPackets), index);
|
||||
}
|
||||
|
||||
public long VersionTotal => Version + Packets.Sum(p => p.VersionTotal);
|
||||
|
||||
public long Eval =>
|
||||
TypeId switch
|
||||
{
|
||||
0 => Packets.Sum(p => p.Eval),
|
||||
1 => Packets.Aggregate(1L, (p, i) => p * i.Eval),
|
||||
2 => Packets.Min(p => p.Eval),
|
||||
3 => Packets.Max(p => p.Eval),
|
||||
4 => Value,
|
||||
5 => Packets[0].Eval > Packets[1].Eval ? 1 : 0,
|
||||
6 => Packets[0].Eval < Packets[1].Eval ? 1 : 0,
|
||||
7 => Packets[0].Eval == Packets[1].Eval ? 1 : 0,
|
||||
_ => throw new ArgumentException("invalid packet type", nameof(TypeId))
|
||||
};
|
||||
}
|
||||
|
||||
public override object Part1() => _packet.VersionTotal;
|
||||
|
||||
public override object Part2() => _packet.Eval;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
C20D718021600ACDC372CD8DE7A057252A49C940239D68978F7970194EA7CCB310088760088803304A0AC1B100721EC298D3307440041CD8B8005D12DFD27CBEEF27D94A4E9B033006A45FE71D665ACC0259C689B1F99679F717003225900465800804E39CE38CE161007E52F1AEF5EE6EC33600BCC29CFFA3D8291006A92CA7E00B4A8F497E16A675EFB6B0058F2D0BD7AE1371DA34E730F66009443C00A566BFDBE643135FEDF321D000C6269EA66545899739ADEAF0EB6C3A200B6F40179DE31CB7B277392FA1C0A95F6E3983A100993801B800021B0722243D00042E0DC7383D332443004E463295176801F29EDDAA853DBB5508802859F2E9D2A9308924F9F31700AA4F39F720C733A669EC7356AC7D8E85C95E123799D4C44C0109C0AF00427E3CC678873F1E633C4020085E60D340109E3196023006040188C910A3A80021B1763FC620004321B4138E52D75A20096E4718D3E50016B19E0BA802325E858762D1802B28AD401A9880310E61041400043E2AC7E8A4800434DB24A384A4019401C92C154B43595B830002BC497ED9CC27CE686A6A43925B8A9CFFE3A9616E5793447004A4BBB749841500B26C5E6E306899C5B4C70924B77EF254B48688041CD004A726ED3FAECBDB2295AEBD984E08E0065C101812E006380126005A80124048CB010D4C03DC900E16A007200B98E00580091EE004B006902004B00410000AF00015933223100688010985116A311803D05E3CC4B300660BC7283C00081CF26491049F3D690E9802739661E00D400010A8B91F2118803310A2F43396699D533005E37E8023311A4BB9961524A4E2C027EC8C6F5952C2528B333FA4AD386C0A56F39C7DB77200C92801019E799E7B96EC6F8B7558C014977BD00480010D89D106240803518E31C4230052C01786F272FF354C8D4D437DF52BC2C300567066550A2A900427E0084C254739FB8E080111E0
|
|
@ -0,0 +1 @@
|
|||
8A004A801A8002F478
|
Loading…
Reference in New Issue