This one felt good. And I hit a new personal best on the global leaderboard of 562/404.
This commit is contained in:
2023-12-07 23:31:57 -06:00
parent 0ba5d244f5
commit 1da4a195aa
7 changed files with 812 additions and 6 deletions

72
src/08.cs Normal file
View File

@ -0,0 +1,72 @@
using Math = aoc2023.Util.Math;
namespace aoc2023;
internal class Day08 : Day
{
private string directions = "";
private readonly Dictionary<string, (string left, string right)> nodes = [];
internal override void Parse()
{
var lines = Util.Parsing.ReadAllLines($"{GetDay()}").ToList();
directions = lines[0];
foreach (var line in lines.Skip(2))
{
var split = line.Split(" = ");
var choices = split[1].Trim('(', ')').Split(", ");
nodes.Add(split[0], (choices[0], choices[1]));
}
}
internal override string Part1()
{
var currNode = "AAA";
int i;
for (i = 0; currNode != "ZZZ"; i++)
{
if (directions[i % directions.Length] == 'R')
{
currNode = nodes[currNode].right;
}
else
{
currNode = nodes[currNode].left;
}
}
return $"Steps from AAA to ZZZ: <+white>{i}";
}
internal override string Part2()
{
List<string> currNodes = [];
foreach (var node in nodes)
{
if (node.Key.EndsWith('A'))
{
currNodes.Add(node.Key);
}
}
List<long> dists = [];
for (int n = 0; n < currNodes.Count; n++)
{
long i;
for (i = 0; !currNodes[n].EndsWith('Z'); i++)
{
if (directions[(int)(i % directions.Length)] == 'R')
{
currNodes[n] = nodes[currNodes[n]].right;
}
else
{
currNodes[n] = nodes[currNodes[n]].left;
}
}
dists.Add(i);
}
long totalDist = Math.LCM([.. dists]);
return $"Steps before all nodes ending in A are simultaneously on a node ending in Z: <+white>{totalDist}";
}
}

View File

@ -1,12 +1,14 @@
namespace aoc2023.Util;
using System.Numerics;
namespace aoc2023.Util;
public static class Math
{
public static ulong GCD(ulong a, ulong b)
public static T GCD<T>(T a, T b) where T : IBinaryInteger<T>
{
while (true)
{
if (b == 0)
if (b == T.Zero)
{
return a;
}
@ -17,13 +19,13 @@ public static class Math
}
}
public static ulong LCM(params ulong[] nums)
public static T LCM<T>(params T[] nums) where T : IBinaryInteger<T>
{
var num = nums.Length;
switch (num)
{
case 0:
return 0;
return T.Zero;
case 1:
return nums[0];
}
@ -37,7 +39,7 @@ public static class Math
return ret;
}
private static ulong lcm(ulong a, ulong b)
private static T lcm<T>(T a, T b) where T : IBinaryInteger<T>
{
return (a * b) / GCD(a, b);
}