104 lines
3.6 KiB
C#
104 lines
3.6 KiB
C#
using AdventOfCode.Core;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace AdventOfCode.Solutions._2023
|
|
{
|
|
public class Day08(InputReader reader) : IChallange
|
|
{
|
|
private InputReader _inputReader = reader;
|
|
|
|
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 = new Dictionary<string, LeftRight>();
|
|
|
|
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 = new Dictionary<string, LeftRight>();
|
|
|
|
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;
|
|
}
|
|
}
|
|
} |