Day 9 solution

As always, plenty of room for improvement, but I'm reasonably satisfied with the core implementation. I'm honestly not sure why the Distinct is needed in the GetBasinSize() result as it's supposed to not even add the point if the point is already in there, but it's late so I'll check that out later.
This commit is contained in:
2021-12-09 00:40:02 -06:00
parent 0dd261b964
commit 2c224483b4
4 changed files with 233 additions and 1 deletions

128
src/09.cs Normal file
View File

@ -0,0 +1,128 @@
namespace aoc2021
{
internal class Day09
{
internal static void Go()
{
Logger.Log("Day 9");
Logger.Log("-----");
var lines = File.ReadAllLines("inputs/09.txt");
byte[,] grid = new byte[lines.Length, lines[0].Length];
for (int i = 0; i < lines.Length; i++)
{
for (int j = 0; j < lines[i].Length; j++)
{
grid[i, j] = (byte)char.GetNumericValue(lines[i][j]);
}
}
Part1(grid);
Part2(grid);
Logger.Log("");
}
private static void Part1(byte[,] grid)
{
using var t = new Timer();
var lowPoints = GetLowPoints(grid);
var totalRisk = lowPoints.Sum(x => grid[x.Item1, x.Item2] + 1);
Logger.Log($"part1: {totalRisk}");
}
private static List<(int, int)> GetLowPoints(byte[,] grid)
{
List<(int, int)> lowPoints = new();
for (int i = 0; i < grid.GetLength(0); i++)
{
for (int j = 0; j < grid.GetLength(1); j++)
{
byte val = grid[i, j];
if (i > 0 && grid[i - 1, j] <= val)
{
continue;
}
if (i < grid.GetLength(0) - 1 && grid[i + 1, j] <= val)
{
continue;
}
if (j > 0 && grid[i, j - 1] <= val)
{
continue;
}
if (j < grid.GetLength(1) - 1 && grid[i, j + 1] <= val)
{
continue;
}
lowPoints.Add((i, j));
}
}
return lowPoints;
}
private static void Part2(byte[,] grid)
{
using var t = new Timer();
var lowPoints = GetLowPoints(grid);
List<int> basins = new();
foreach (var point in lowPoints)
{
var basinPoints = GetBasinSize(grid, point.Item1, point.Item2);
basins.Add(basinPoints.Distinct().Count() + 1);
}
var top3Mult = basins.OrderByDescending(x => x).Take(3).Aggregate(1, (x,y) => x * y);
Logger.Log($"part2: {top3Mult}");
}
private static List<(int, int)> GetBasinSize(byte[,] grid, int i, int j)
{
List<(int, int)> basinPoints = new();
if (i >= grid.GetLength(0) || j >= grid.GetLength(1) || i < 0 || j < 0)
{
return new();
}
if (!basinPoints.Contains((i - 1, j)) && IsBasinPoint(grid, grid[i, j], i - 1, j))
{
basinPoints.Add((i - 1, j));
basinPoints.AddRange(GetBasinSize(grid, i - 1, j));
}
if (!basinPoints.Contains((i + 1, j)) && IsBasinPoint(grid, grid[i, j], i + 1, j))
{
basinPoints.Add((i + 1, j));
basinPoints.AddRange(GetBasinSize(grid, i + 1, j));
}
if (!basinPoints.Contains((i, j - 1)) && IsBasinPoint(grid, grid[i, j], i, j - 1))
{
basinPoints.Add((i, j - 1));
basinPoints.AddRange(GetBasinSize(grid, i, j - 1));
}
if (!basinPoints.Contains((i, j + 1)) && IsBasinPoint(grid, grid[i, j], i, j + 1))
{
basinPoints.Add((i, j + 1));
basinPoints.AddRange(GetBasinSize(grid, i, j + 1));
}
return basinPoints;
}
private static bool IsBasinPoint(byte[,] grid, byte val, int i, int j)
{
if (i >= grid.GetLength(0) || j >= grid.GetLength(1) || i < 0 || j < 0)
{
return false;
}
if (grid[i, j] == 9 || val == 9)
{
return false;
}
return grid[i, j] > val;
}
}
}

View File

@ -3,4 +3,5 @@
//aoc2021.Day05.Go();
//aoc2021.Day06.Go();
//aoc2021.Day07.Go();
aoc2021.Day08.Go();
//aoc2021.Day08.Go();
aoc2021.Day09.Go();