Add Day 12 Part 1
This commit is contained in:
125
Day12/Program.cs
Normal file
125
Day12/Program.cs
Normal file
@@ -0,0 +1,125 @@
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user