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 GetSolutionPart1() { IAsyncEnumerator lines = _inputReader.ReadAsStringLine().GetAsyncEnumerator(); await lines.MoveNextAsync(); string route = lines.Current; await lines.MoveNextAsync(); Dictionary 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 GetSolutionPart2() { IAsyncEnumerator lines = _inputReader.ReadAsStringLine().GetAsyncEnumerator(); await lines.MoveNextAsync(); string route = lines.Current; await lines.MoveNextAsync(); Dictionary routes = []; while (await lines.MoveNextAsync()) { var parsed = Parse(lines.Current); routes.Add(parsed.From, parsed.To); } await lines.DisposeAsync(); List currentPoints = routes.Keys.Where(k => k.EndsWith('A')).ToList(); List 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; } } }