Files

143 lines
3.4 KiB
C#
Raw Permalink Normal View History

2024-12-10 14:30:51 +02:00
var rawTopographicMap = File.ReadLines("input.txt");
var topographicMap = CreateTopographicMap(rawTopographicMap);
var availableDirections = new List<(int, int)>()
{
(-1, 0), // Up
(1, 0), // Down
(0, -1), // Left
(0, 1) // Right
};
Console.WriteLine($"Part1: {Part1(topographicMap, availableDirections)}\nPart2: {Part2(topographicMap, availableDirections)}");
int Part2(int[,] mapInput, List<(int, int)> directions)
{
var totalRating = 0;
for (var r = 0; r < mapInput.GetLength(0); r++)
{
for (var c = 0; c < mapInput.GetLength(1); c++)
{
if (mapInput[r, c] == 0)
{
totalRating += FindDistinctTrails(r, c, mapInput, directions);
}
}
}
return totalRating;
}
2024-12-10 14:37:56 +02:00
// Could reuse the trailHead method with minor edits
2024-12-10 14:30:51 +02:00
int FindDistinctTrails(int r, int c, int[,] mapInput, List<(int, int)> directions)
{
var stack = new Stack<List<(int, int)>>();
stack.Push(new List<(int, int)> { (r, c) });
var trails = 0;
while (stack.Count > 0)
{
var currentPath = stack.Pop();
var (cr, cc) = currentPath[^1];
if (mapInput[cr, cc] == 9)
{
trails++;
continue;
}
foreach (var (dr, dc) in directions)
{
var nr = cr + dr;
var nc = cc + dc;
if (nr >= 0 && nr < mapInput.GetLength(0) && nc >= 0 && nc < mapInput.GetLength(1) &&
mapInput[nr, nc] == mapInput[cr, cc] + 1)
{
var nextPath = new List<(int, int)>(currentPath);
nextPath.Add((nr, nc));
stack.Push(nextPath);
}
}
}
return trails;
}
int Part1(int[,] map, List<(int, int)> directions)
{
var totalScore = 0;
for (var row = 0; row < map.GetLength(0); row++)
{
for (var column = 0; column < map.GetLength(1); column++)
{
if (map[row, column] == 0)
{
totalScore += TrailHead(row, column, map, directions);
}
}
}
return totalScore;
}
int TrailHead(int startRow, int startColumn, int[,] map, List<(int, int)> directions)
{
var rows = map.GetLength(0);
var cols = map.GetLength(1);
var queue = new Queue<(int, int)>();
var visited = new HashSet<(int, int)>();
var reachableNines = new HashSet<(int, int)>();
queue.Enqueue((startRow, startColumn));
while (queue.Count > 0)
{
var (r, c) = queue.Dequeue();
if (visited.Contains((r, c)))
continue;
visited.Add((r, c));
if (map[r, c] == 9)
{
reachableNines.Add((r, c));
continue;
}
foreach (var dir in directions)
{
var nr = r + dir.Item1;
var nc = c + dir.Item2;
if (nr >= 0 && nr < rows && nc >= 0 && nc < cols)
{
if (map[nr, nc] == map[r, c] + 1)
{
queue.Enqueue((nr, nc));
}
}
}
}
return reachableNines.Count;
}
int[,] CreateTopographicMap(IEnumerable<string> lines)
{
var lineList = lines.Select(line => line.Trim()).ToList();
var map = new int[lineList.Count, lineList[0].Length];
for (var r = 0; r < map.GetLength(0); r++)
{
for (var c = 0; c < map.GetLength(1); c++)
{
map[r, c] = lineList[r][c] - '0';
}
}
return map;
}