Finally, the first topographical map puzzle. There seems to be one or two of these every year, and this one seems a bit simpler than the others have been. A depth-first search of a relatively simple map; in this case, even fixed-length with a rule that, by defintion, can't go back on itself.
private int CountTrails(int x, int y)
{
var trailEnds = new HashSet<(int, int)>();
GetTrailEnds(x, y, 0, trailEnds);
return trailEnds.Count;
}
private void GetTrailEnds(int x, int y, int height, HashSet<(int, int)> knownEnds)
{
if (!Utils.IsInBounds(map, x, y) || map[x][y] != height) return;
if (height == 9 && map[x][y] == height)
{
knownEnds.Add((x, y));
return;
}
GetTrailEnds(x + 1, y, height + 1, knownEnds);
GetTrailEnds(x - 1, y, height + 1, knownEnds);
GetTrailEnds(x, y + 1, height + 1, knownEnds);
GetTrailEnds(x, y - 1, height + 1, knownEnds);
}
Ha! I accidentally did part 2 initially because I misunderstood part 1. This is actually easier in a vaccum...
private int CountUniqueTrails(int x, int y, int height = 0)
{
if (height == 9 && Utils.IsInBounds(map, x, y) && map[x][y] == height) return 1;
if (!Utils.IsInBounds(map, x, y) || map[x][y] != height) return 0;
return CountUniqueTrails(x + 1, y, height + 1)
+ CountUniqueTrails(x - 1, y, height + 1)
+ CountUniqueTrails(x, y + 1, height + 1)
+ CountUniqueTrails(x, y - 1, height + 1);
}
🎂