Files
AdventOfCode/AdventOfCode2024/Day04.cs
2024-12-05 01:23:46 +01:00

137 lines
4.1 KiB
C#

namespace AdventOfCode2024;
/*
--- Day 4: Ceres Search ---
"Looks like the Chief's not here. Next!" One of The Historians pulls out a device and pushes the only button on it. After a brief flash, you recognize the interior of the Ceres monitoring station!
As the search for the Chief continues, a small Elf who lives on the station tugs on your shirt; she'd like to know if you could help her with her word search (your puzzle input). She only has to find one word: XMAS.
This word search allows words to be horizontal, vertical, diagonal, written backwards, or even overlapping other words. It's a little unusual, though, as you don't merely need to find one instance of XMAS - you need to find all of them. Here are a few ways XMAS might appear, where irrelevant characters have been replaced with .:
..X...
.SAMX.
.A..A.
XMAS.S
.X....
The actual word search will be full of letters instead. For example:
MMMSXXMASM
MSAMXMSMSA
AMXSXMAAMM
MSAMASMSMX
XMASAMXAMM
XXAMMXXAMA
SMSMSASXSS
SAXAMASAAA
MAMMMXMMMM
MXMXAXMASX
In this word search, XMAS occurs a total of 18 times; here's the same word search again, but where letters not involved in any XMAS have been replaced with .:
....XXMAS.
.SAMXMS...
...S..A...
..A.A.MS.X
XMASAMX.MM
X.....XA.A
S.S.S.S.SS
.A.A.A.A.A
..M.M.M.MM
.X.X.XMASX
Take a look at the little Elf's word search. How many times does XMAS appear?
*/
public class Day04 : IDay
{
public string ResolvePart1(string[] inputs)
{
char[,] grid = ConvertToGrid(inputs);
const string word = "XMAS";
List<(int dx, int dy)> directions = [
(0, -1),
(1, 0),
(0, 1),
(-1, 0),
(-1, -1),
(1, -1),
(-1, 1),
(1, 1),
];
int totalMatches = 0;
for (int x = 0; x < grid.GetLength(0); x++)
{
for (int y = 0; y < grid.GetLength(1); y++)
{
for (int i = 0; i < directions.Count; i++)
{
if (CheckMatch(grid, word, x, y, directions[i].dx, directions[i].dy))
{
totalMatches++;
}
}
}
}
return totalMatches.ToString();
}
private static char[,] ConvertToGrid(string[] inputs)
{
int height = inputs.Count(s => s.Length > 0);
int width = inputs.Where(s => s.Length > 0).Select(s => s.Length).Min();
char[,] grid = new char[width, height];
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
grid[x, y] = inputs[y][x];
}
}
return grid;
}
private static bool CheckMatch(char[,] grid, string word, int x, int y, int dx, int dy)
{
int matched = 0;
if (x < 0 || x >= grid.GetLength(0) || y < 0 || y >= grid.GetLength(1)) { return false; }
while (grid[x, y] == word[matched])
{
matched++;
if (matched == word.Length) { return true; }
x += dx;
y += dy;
if (x < 0 || x >= grid.GetLength(0) || y < 0 || y >= grid.GetLength(1)) { break; }
}
return false;
}
public string ResolvePart2(string[] inputs)
{
char[,] grid = ConvertToGrid(inputs);
const string word = "MAS";
int totalMatches = 0;
for (int x = 0; x < grid.GetLength(0); x++)
{
for (int y = 0; y < grid.GetLength(1); y++)
{
if (
(CheckMatch(grid, word, x - 1, y - 1, 1, 1) && CheckMatch(grid, word, x - 1, y + 1, 1, -1)) ||
(CheckMatch(grid, word, x - 1, y - 1, 1, 1) && CheckMatch(grid, word, x + 1, y - 1, -1, 1)) ||
(CheckMatch(grid, word, x + 1, y + 1, -1, -1) && CheckMatch(grid, word, x - 1, y + 1, 1, -1)) ||
(CheckMatch(grid, word, x + 1, y + 1, -1, -1) && CheckMatch(grid, word, x + 1, y - 1, -1, 1))
)
{
totalMatches++;
}
}
}
return totalMatches.ToString();
}
}