ben
/
aoc
1
0
Fork 0
aoc/AOC2022/Day12.cs

57 lines
2.0 KiB
C#

namespace AOC2022;
/// <summary>
/// Day 12: <a href="https://adventofcode.com/2022/day/12"/>
/// </summary>
public sealed class Day12() : Day(2022, 12, "Hill Climbing Algorithm")
{
private readonly Dictionary<(int x, int y), int> _grid = [];
private static readonly List<(int x, int y)> Directions = [(-1, 0), (1, 0), (0, -1), (0, 1)];
private (int x, int y) _startCoord, _destCoord;
public override void ProcessInput()
{
foreach (var (y, line) in Input.Indexed())
foreach (var (x, c) in line.Indexed())
switch (c)
{
case 'S':
_startCoord = (x, y);
_grid[(x, y)] = 0;
break;
case 'E':
_destCoord = (x, y);
_grid[(x, y)] = 25;
break;
default:
_grid[(x, y)] = c - 'a';
break;
}
}
private int ShortestDistance((int x, int y) startCoord, (int x, int y)? destCoord, int? destVal = null)
{
var queue = new Queue<(int x, int y, int steps)>();
var seen = new HashSet<(int x, int y)> { startCoord };
queue.Enqueue((startCoord.x, startCoord.y, 0));
while (queue.Count != 0)
{
var (x, y, steps) = queue.Dequeue();
if (destCoord == (x, y) || (destVal != null && _grid[(x, y)] == destVal)) return steps;
foreach (var subPath in Directions
.Select(direction => (x + direction.x, y + direction.y))
.Where(s => _grid.ContainsKey(s))
.Where(s => _grid[s] >= _grid[(x, y)] - 1)
.Where(s => seen.Add(s)))
queue.Enqueue((subPath.Item1, subPath.Item2, steps + 1));
}
throw new("Path not found");
}
public override object Part1() => ShortestDistance(_destCoord, _startCoord);
public override object Part2() => ShortestDistance(_destCoord, null, 0);
}