2021aoc/Day9.cs

93 lines
3.1 KiB
C#

// #define Day9
#if Day9
var linesSplit = File.ReadAllLines("day9/input")
.ToList();
long sum = 0;
for (int row = 0; row < linesSplit.Count; row++) {
for (int col = 0; col < linesSplit[row].Length; col++) {
sum += Check(linesSplit, row, col, int.Parse(linesSplit[row][col].ToString()));
}
}
Console.WriteLine(sum);
// PartTwo
List<long> basinSizes = new List<long>();
for (int row = 0; row < linesSplit.Count; row++) {
for (int col = 0; col < linesSplit[row].Length; col++) {
if (Check(linesSplit, row, col, int.Parse(linesSplit[row][col].ToString())) > 0) {
var cur = new Point(row, col, int.Parse(linesSplit[row][col].ToString()));
var inBasin = Basin(linesSplit, cur, new HashSet<Point>() {cur});
basinSizes.Add(inBasin.Count);
}
}
}
var res = basinSizes.OrderByDescending(x => x).Take(3).Aggregate(1L, (x, y) => x * y);
Console.WriteLine(res);
HashSet<Point> Basin(List<string> map, Point cur, HashSet<Point> visited) {
if (cur.row > 0) {
var above = new Point(cur.row-1, cur.col, int.Parse(map[cur.row-1][cur.col].ToString()));
if (above.value != 9 && cur.value < above.value && !visited.Contains(above)) {
var newVisited = new HashSet<Point>(visited);
newVisited.Add(above);
visited = Basin(linesSplit, above, newVisited);
}
}
if (cur.row < map.Count-1) {
var above = new Point(cur.row+1, cur.col, int.Parse(map[cur.row+1][cur.col].ToString()));
if (above.value != 9 && cur.value < above.value && !visited.Contains(above)) {
var newVisited = new HashSet<Point>(visited);
newVisited.Add(above);
visited = Basin(linesSplit, above, newVisited);
}
}
if (cur.col < map[cur.row].Length-1) {
var above = new Point(cur.row, cur.col+1, int.Parse(map[cur.row][cur.col+1].ToString()));
if (above.value != 9 && cur.value < above.value && !visited.Contains(above)) {
var newVisited = new HashSet<Point>(visited);
newVisited.Add(above);
visited = Basin(linesSplit, above, newVisited);
}
}
if (cur.col >0) {
var above = new Point(cur.row, cur.col-1, int.Parse(map[cur.row][cur.col-1].ToString()));
if (above.value != 9 && cur.value < above.value && !visited.Contains(above)) {
var newVisited = new HashSet<Point>(visited);
newVisited.Add(above);
visited = Basin(linesSplit, above, newVisited);
}
}
return visited;
}
int Check(List<string> map, int row, int col, int value) {
if (row > 0) {
if (value >= int.Parse(map[row-1][col].ToString())) {
return 0;
}
}
if (row < map.Count-1) {
if (value >= int.Parse(map[row+1][col].ToString())) {
return 0;
}
}
if (col < map[row].Length - 1) {
if (value >= int.Parse(map[row][col+1].ToString())) {
return 0;
}
}
if (col > 0) {
if (value >= int.Parse(map[row][col-1].ToString())) {
return 0;
}
}
return 1 + value;
}
record Point(int row, int col, int value);
#endif