Add day 12
This commit is contained in:
155
Days/Day12.cs
Normal file
155
Days/Day12.cs
Normal file
@@ -0,0 +1,155 @@
|
||||
using System.Collections.Frozen;
|
||||
using System.Numerics;
|
||||
using Spectre.Console;
|
||||
|
||||
namespace AdventOfCode.Days;
|
||||
|
||||
public class Day12 : Day
|
||||
{
|
||||
public override int Number => 12;
|
||||
public override string Name => "Garden Groups";
|
||||
|
||||
private const int GridSize = 140;
|
||||
|
||||
public override void RunPart1(bool display = true)
|
||||
{
|
||||
var areas = ParseAreas();
|
||||
|
||||
var visited = new HashSet<Point>();
|
||||
var totalPrice = 0;
|
||||
|
||||
var currentArea = 0;
|
||||
var currentPerimeter = 0;
|
||||
|
||||
for (var y = 0; y < GridSize; y++)
|
||||
{
|
||||
for (var x = 0; x < GridSize; x++)
|
||||
{
|
||||
// Skip already visited points
|
||||
if (visited.Contains(new Point(x, y)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var id = areas[x, y];
|
||||
|
||||
ComputeAreaPrice(new Point(x, y), id, ref currentArea, ref currentPerimeter);
|
||||
|
||||
// Add price of fencing this area
|
||||
totalPrice += currentArea * currentPerimeter;
|
||||
|
||||
currentArea = 0;
|
||||
currentPerimeter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (display)
|
||||
{
|
||||
AnsiConsole.MarkupLine($"[green]Total pricing: [yellow]{totalPrice}[/][/]");
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
void ComputeAreaPrice(Point position, byte id, ref int area, ref int perimeter)
|
||||
{
|
||||
if (!visited.Add(position))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Update area and perimeter
|
||||
area++;
|
||||
perimeter += 4;
|
||||
|
||||
var left = position with { X = position.X - 1 };
|
||||
var right = position with { X = position.X + 1 };
|
||||
var up = position with { Y = position.Y - 1 };
|
||||
var down = position with { Y = position.Y + 1 };
|
||||
|
||||
if (left is { X: >= 0 and < GridSize } && areas[left.X, left.Y] == id)
|
||||
{
|
||||
perimeter--;
|
||||
|
||||
ComputeAreaPrice(left, id, ref area, ref perimeter);
|
||||
}
|
||||
|
||||
if (right is { X: >= 0 and < GridSize } && areas[right.X, right.Y] == id)
|
||||
{
|
||||
perimeter--;
|
||||
|
||||
ComputeAreaPrice(right, id, ref area, ref perimeter);
|
||||
}
|
||||
|
||||
if (up is { Y: >= 0 and < GridSize } && areas[up.X, up.Y] == id)
|
||||
{
|
||||
perimeter--;
|
||||
|
||||
ComputeAreaPrice(up, id, ref area, ref perimeter);
|
||||
}
|
||||
|
||||
if (down is { Y: >= 0 and < GridSize } && areas[down.X, down.Y] == id)
|
||||
{
|
||||
perimeter--;
|
||||
|
||||
ComputeAreaPrice(down, id, ref area, ref perimeter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void RunPart2(bool display = true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private byte[,] ParseAreas()
|
||||
{
|
||||
var areas = new byte[GridSize, GridSize];
|
||||
|
||||
int y = 0;
|
||||
|
||||
foreach (var line in Input.AsSpan().EnumerateLines())
|
||||
{
|
||||
int x = 0;
|
||||
|
||||
foreach (var area in line)
|
||||
{
|
||||
areas[x, y] = (byte)(area - 'A');
|
||||
|
||||
x++;
|
||||
}
|
||||
|
||||
y++;
|
||||
}
|
||||
|
||||
return areas;
|
||||
}
|
||||
|
||||
private readonly record struct Point(int X, int Y)
|
||||
: IAdditionOperators<Point, Point, Point>,
|
||||
ISubtractionOperators<Point, Point, Point>,
|
||||
IMultiplyOperators<Point, int, Point>
|
||||
{
|
||||
public static Point operator +(Point left, Point right)
|
||||
{
|
||||
return new Point(left.X + right.X, left.Y + right.Y);
|
||||
}
|
||||
|
||||
public static Point operator -(Point left, Point right)
|
||||
{
|
||||
return new Point(left.X - right.X, left.Y - right.Y);
|
||||
}
|
||||
|
||||
public static Point operator *(Point left, int right)
|
||||
{
|
||||
return new Point(left.X * right, left.Y * right);
|
||||
}
|
||||
|
||||
public static Point operator *(int left, Point right)
|
||||
{
|
||||
return new Point(right.X * left, right.Y * left);
|
||||
}
|
||||
|
||||
public static implicit operator Point((int X, int Y) point)
|
||||
=> new(point.X, point.Y);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user