Files
Project-AOC-2024/Day12/Program.cs
Dimitrios Kaltzidis d98019ff8b Add Day 12 Part 1
2024-12-12 08:27:53 +02:00

125 lines
3.0 KiB
C#

var lines = File.ReadAllLines("input.txt");
var grid = CreateGrid(lines);
int[][] directions = new int[][]
{
[-1, 0],
[0, -1],
[0, 1],
[1, 0]
};
var part1 = Part1(grid, directions);
Console.WriteLine($"Part1: {part1}\n");
int Part1(char[,] grid, int[][] directions)
{
var rows = grid.GetLength(0);
var columns = grid.GetLength(1);
var neighbourDictionary = new Dictionary<(int, int), HashSet<(int, int)>>();
for (var i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
neighbourDictionary[(i, j)] = new HashSet<(int, int)>();
foreach (var dir in directions)
{
var di = dir[0];
var dj = dir[1];
if (i + di >= 0 && i + di < rows && j + dj >= 0 && j + dj < columns)
{
if (grid[i, j] == grid[i + di, j + dj])
{
neighbourDictionary[(i, j)].Add((i + di, j + dj));
}
}
}
}
}
var regions = new List<HashSet<(int, int)>>();
var remainingPoints = new HashSet<(int, int)>();
for (var i = 0; i < rows; i++)
{
for (var j = 0; j < columns; j++)
{
remainingPoints.Add((i, j));
}
}
while (remainingPoints.Count > 0)
{
var point = remainingPoints.First();
remainingPoints.Remove(point);
var region = GetRegion(point, neighbourDictionary);
regions.Add(region);
remainingPoints.ExceptWith(region);
}
return regions.Sum(region => Perimeter(region, neighbourDictionary) * region.Count);
}
int CountSplitSegments(List<(int, int, int, string)> lines)
{
if (lines.Count == 0) return 0;
var segmentCount = 1;
for (var i = 1; i < lines.Count; i++)
{
var prev = lines[i - 1];
var curr = lines[i];
var isContiguous =
(prev.Item1 == curr.Item1 && curr.Item2 - prev.Item2 == 1 && curr.Item3 == prev.Item3);
if (!isContiguous)
{
segmentCount++;
}
}
return segmentCount;
}
HashSet<(int, int)> GetRegion((int, int) point, Dictionary<(int, int), HashSet<(int, int)>> neighbourDict)
{
var region = new HashSet<(int, int)>();
var remaining = new HashSet<(int, int)> { point };
while (remaining.Count > 0)
{
var curPoint = remaining.First();
remaining.Remove(curPoint);
region.Add(curPoint);
var newRemaining = neighbourDict[curPoint].Except(region);
remaining.UnionWith(newRemaining);
}
return region;
}
int Perimeter(HashSet<(int, int)> region, Dictionary<(int, int), HashSet<(int, int)>> neighbourDict)
{
return region.Sum(point => 4 - neighbourDict[point].Count);
}
char[,] CreateGrid(string[] lines)
{
var grid = new char[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] = lines[i][j];
}
}
return grid;
}