using System.Collections.Generic; using System.Data.Common; using System.IO; using System.Linq; using AdvenOfCode.Contracts; using Coordinate = (int x, int y); namespace AoC_2025; public class Day07 : IPuzzleSolver { private string[] ParsePuzzleInput(string path) { var puzzleInput = File.ReadAllLines(path) .Where(line => !string.IsNullOrWhiteSpace(line)) .ToArray(); return puzzleInput; } public long SolvePart1(string pathToPuzzleInput) { var grid = ParsePuzzleInput(pathToPuzzleInput); var start = GetStart(grid); var count = TraverseGridAndCountSplitters(grid, start); return count; } public long SolvePart2(string pathToPuzzleInput) { var grid = ParsePuzzleInput(pathToPuzzleInput); var start = GetStart(grid); var count = GetNodesTraversedWitTimelineCount(grid, start, [], []); return count[start]; } private Coordinate GetStart(string[] grid) { return (0, grid[0].IndexOf('S')); } private long TraverseGridAndCountSplitters(string[] grid, Coordinate start) { HashSet visited = [start]; var seen = new Queue(); seen.Enqueue(start); var splittersHit = 0L; while (seen.TryDequeue(out var current)) { if (current.x >= grid.Length) continue; if (current.y >= grid[0].Length || current.y < 0) continue; if (grid[current.x][current.y] == '^') { splittersHit++; var nextLeft = (current.x, current.y - 1); var nextRight = (current.x, current.y + 1); if (visited.Add(nextLeft)) seen.Enqueue(nextLeft); if (visited.Add(nextRight)) seen.Enqueue(nextRight); } else { var next = (current.x + 1, current.y); if (visited.Add(next)) seen.Enqueue(next); } } return splittersHit; } private Dictionary GetNodesTraversedWitTimelineCount(string[] grid, Coordinate current, HashSet path, Dictionary nodeCountVisited) { if (current.x >= grid.Length || nodeCountVisited.ContainsKey(current)) { var addAmount = nodeCountVisited.GetValueOrDefault(current, 1); foreach (var node in path) { nodeCountVisited[node] += addAmount; } return nodeCountVisited; } nodeCountVisited[current] = 0; path.Add(current); if (grid[current.x][current.y] == '^') { var resLeft = GetNodesTraversedWitTimelineCount(grid, (current.x, current.y - 1), [..path], nodeCountVisited); var resRight = GetNodesTraversedWitTimelineCount(grid, (current.x, current.y + 1), [..path], resLeft); return resRight; } else { var res = GetNodesTraversedWitTimelineCount(grid, (current.x + 1, current.y), [..path], nodeCountVisited); return res; } } }