AdventOfCode/AdventOfCode.Solutions/2023/Day 08/Day08.cs
2024-12-01 10:17:24 +01:00

112 lines
3.7 KiB
C#

using AdventOfCode.Core.Shared.IO;
using System.Text.RegularExpressions;
namespace AdventOfCode.Solutions._2023
{
public class Day08 : IChallange
{
public int Year => 2023;
public int Day => 8;
private readonly IInputReader _inputReader;
public Day08(IInputReader inputReader)
{
_inputReader = inputReader;
_inputReader.SetInput(this);
}
public async Task<string> GetSolutionPart1()
{
IAsyncEnumerator<string> lines = _inputReader.ReadAsStringLine().GetAsyncEnumerator();
await lines.MoveNextAsync();
string route = lines.Current;
await lines.MoveNextAsync();
Dictionary<string, LeftRight> routes = [];
while(await lines.MoveNextAsync())
{
var parsed = Parse(lines.Current);
routes.Add(parsed.From, parsed.To);
}
await lines.DisposeAsync();
string currentWaypoint = "AAA";
int steps = 0;
do
{
char directionChar = route[steps % route.Length];
steps++;
currentWaypoint = directionChar == 'L' ? routes[currentWaypoint].Left : routes[currentWaypoint].Right;
}
while (currentWaypoint != "ZZZ");
return steps.ToString();
}
public async Task<string> GetSolutionPart2()
{
IAsyncEnumerator<string> lines = _inputReader.ReadAsStringLine().GetAsyncEnumerator();
await lines.MoveNextAsync();
string route = lines.Current;
await lines.MoveNextAsync();
Dictionary<string, LeftRight> routes = [];
while (await lines.MoveNextAsync())
{
var parsed = Parse(lines.Current);
routes.Add(parsed.From, parsed.To);
}
await lines.DisposeAsync();
List<string> currentPoints = routes.Keys.Where(k => k.EndsWith('A')).ToList();
List<int> done = [];
int steps = 0;
long totalRequired = 0;
do
{
char directionChar = route[steps % route.Length];
steps++;
currentPoints = currentPoints.Select(s => directionChar == 'L' ? routes[s].Left : routes[s].Right).ToList();
if (currentPoints.Any(s => s.EndsWith('Z')))
{
Console.WriteLine($"Direction index: {steps % route.Length} on iteration {(int)(steps / route.Length)}");
for (int i = 0; i < currentPoints.Count; i++)
{
if (!done.Contains(i) && currentPoints[i].EndsWith('Z'))
{
done.Add(i);
totalRequired = totalRequired == 0 ? (steps / route.Length) : totalRequired * (steps / route.Length);
Console.WriteLine($"[{i}] {currentPoints[i]}");
}
}
Console.WriteLine();
}
}
while (done.Count != currentPoints.Count);
return (totalRequired * route.Length).ToString();
}
private static (string From, LeftRight To) Parse(string line){
MatchCollection collection = Regex.Matches(line, @"[\dA-Z]{3}");
return (collection[0].Value, new LeftRight(collection[1].Value, collection[2].Value));
}
private record LeftRight(string left, string right)
{
public string Left { get; } = left;
public string Right { get; } = right;
}
}
}