From ca86573f8fdc7a6162a23a01684175654b077027 Mon Sep 17 00:00:00 2001 From: Parnic Date: Tue, 10 Dec 2024 09:10:08 -0600 Subject: [PATCH] Day 10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🎵 All I need for Advent is my ivec2, my ivec2, my ivec2... --- src/10.cs | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 src/10.cs diff --git a/src/10.cs b/src/10.cs new file mode 100644 index 0000000..5c78dea --- /dev/null +++ b/src/10.cs @@ -0,0 +1,119 @@ +using aoc2024.Util; + +namespace aoc2024; + +internal class Day10 : Day +{ + int[][] grid = new int[10][]; + internal override void Parse() + { + var lines = Util.Parsing.ReadAllLines($"{GetDay()}").ToList(); + grid = new int[lines.Count][]; + for (int y = 0; y < lines.Count; y++) + { + var row = new int[lines[y].Length]; + for (int x = 0; x < row.Length; x++) + { + try + { + row[x] = int.Parse(lines[y][x].ToString()); + } + catch + { + // support example inputs with '.' as part of the path + row[x] = -1; + } + } + + grid[y] = row; + } + } + + internal override string Part1() + { + Queue<(ivec2 pos, ivec2 start)> paths = []; + Dictionary> trails = []; + for (int y = 0; y < grid.Length; y++) + { + for (int x = 0; x < grid[y].Length; x++) + { + if (grid[y][x] == 0) + { + paths.Enqueue((new ivec2(x, y), new ivec2(x, y))); + } + } + } + + while (paths.TryDequeue(out var segment)) + { + foreach (var pt in segment.pos.GetBoundedOrthogonalNeighbors(0, 0, grid[0].Length - 1, grid.Length - 1)) + { + if (grid[pt.y][pt.x] != grid[segment.pos.y][segment.pos.x] + 1) + { + continue; + } + + if (grid[pt.y][pt.x] == 9) + { + if (!trails.TryAdd(segment.start, [pt])) + { + trails[segment.start].Add(pt); + } + + continue; + } + + paths.Enqueue((pt, segment.start)); + } + } + + return $"Trailhead scores sum: <+white>{trails.Sum(t => t.Value.Count)}"; + } + + internal override string Part2() + { + Queue<(ivec2 pos, ivec2 start)> paths = []; + Dictionary> trails = []; + for (int y = 0; y < grid.Length; y++) + { + for (int x = 0; x < grid[y].Length; x++) + { + if (grid[y][x] == 0) + { + paths.Enqueue((new ivec2(x, y), new ivec2(x, y))); + } + } + } + + while (paths.TryDequeue(out var segment)) + { + foreach (var pt in segment.pos.GetBoundedOrthogonalNeighbors(0, 0, grid[0].Length - 1, grid.Length - 1)) + { + if (grid[pt.y][pt.x] != grid[segment.pos.y][segment.pos.x] + 1) + { + continue; + } + + if (grid[pt.y][pt.x] == 9) + { + if (!trails.TryGetValue(segment.start, out var value)) + { + value = []; + trails.Add(segment.start, value); + } + + if (!value.TryAdd(pt, 1)) + { + value[pt]++; + } + + continue; + } + + paths.Enqueue((pt, segment.start)); + } + } + + return $"Trailhead ratings sum: <+white>{trails.Sum(t => t.Value.Sum(e => e.Value))}"; + } +}