136 lines
3.4 KiB
C#
136 lines
3.4 KiB
C#
using Spectre.Console;
|
|
|
|
namespace AdventOfCode.Days;
|
|
|
|
public class Day4 : Day
|
|
{
|
|
public override int Number => 4;
|
|
public override string Name => "Ceres Search";
|
|
|
|
public override void RunPart1(bool display = true)
|
|
{
|
|
var xmasCount = 0;
|
|
|
|
var grid = Input.AsCharGrid();
|
|
|
|
for (int x = 0; x < grid.GetLength(0); x++)
|
|
{
|
|
for (int y = 0; y < grid.GetLength(1); y++)
|
|
{
|
|
xmasCount += CheckXmas(x, y);
|
|
}
|
|
}
|
|
|
|
if (display)
|
|
{
|
|
AnsiConsole.MarkupLine($"[green]Number of safe reports: [yellow]{xmasCount}[/][/]");
|
|
}
|
|
|
|
return;
|
|
|
|
int CheckXmas(int x, int y)
|
|
{
|
|
(int xOffset, int yOffset)[] patterns = [
|
|
(1, 0),
|
|
(-1, 0),
|
|
(0, 1),
|
|
(0, -1),
|
|
(1, 1),
|
|
(1, -1),
|
|
(-1, 1),
|
|
(-1, -1)
|
|
];
|
|
|
|
char[] word = ['X', 'M', 'A', 'S'];
|
|
|
|
int count = 0;
|
|
|
|
foreach (var pattern in patterns)
|
|
{
|
|
bool valid = true;
|
|
|
|
for (int i = 0; i < word.Length; i++)
|
|
{
|
|
var xTarget = x + (pattern.xOffset * i);
|
|
var yTarget = y + (pattern.yOffset * i);
|
|
|
|
if (xTarget < 0 || xTarget >= grid.GetLength(0)
|
|
|| yTarget < 0 || yTarget >= grid.GetLength(1)
|
|
|| word[i] != grid[xTarget, yTarget])
|
|
{
|
|
valid = false;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (valid)
|
|
{
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
}
|
|
|
|
public override void RunPart2(bool display = true)
|
|
{
|
|
var xmasCount = 0;
|
|
|
|
var grid = Input.AsCharGrid();
|
|
|
|
for (int x = 0; x < grid.GetLength(0); x++)
|
|
{
|
|
for (int y = 0; y < grid.GetLength(1); y++)
|
|
{
|
|
xmasCount += CheckXmas(x, y);
|
|
}
|
|
}
|
|
|
|
if (display)
|
|
{
|
|
AnsiConsole.MarkupLine($"[green]Number of safe reports: [yellow]{xmasCount}[/][/]");
|
|
}
|
|
|
|
return;
|
|
|
|
int CheckXmas(int x, int y)
|
|
{
|
|
((int xOffset, int yOffset) first, (int xOffset, int yOffset) second)[] patterns = [
|
|
((-1, -1), (-1, 1)),
|
|
((-1, -1), (1, -1)),
|
|
((1, -1), (1, 1)),
|
|
((1, 1), (-1, 1))
|
|
];
|
|
|
|
char[] word = ['M', 'S'];
|
|
|
|
// Center element of the cross must be an 'A'
|
|
if (grid[x, y] != 'A')
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
// Make sure we're not going out of bounds
|
|
if (x - 1 < 0 || x + 1 >= grid.GetLength(0) ||
|
|
y - 1 < 0 || y + 1 >= grid.GetLength(1))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int count = 0;
|
|
|
|
foreach (var (first, second) in patterns)
|
|
{
|
|
if (grid[x + first.xOffset, y + first.yOffset] is 'M' && grid[x - first.xOffset, y - first.yOffset] is 'S' &&
|
|
grid[x + second.xOffset, y + second.yOffset] is 'M' && grid[x - second.xOffset, y - second.yOffset] is 'S')
|
|
{
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
}
|
|
} |