AdventOfCode/AdventOfCode.Solutions/2024/Day 04/Day04.cs
2024-12-04 13:28:55 +01:00

107 lines
3.4 KiB
C#

using AdventOfCode.Core.Shared.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks.Dataflow;
namespace AdventOfCode.Solutions._2024
{
public class Day04 : IChallange
{
public int Year => 2024;
public int Day => 4;
private readonly IInputReader _inputReader;
public Day04(IInputReader inputReader)
{
_inputReader = inputReader;
_inputReader.SetInput(this);
}
//18
//2514
public async Task<string> GetSolutionPart1()
{
Grid<Point> grid = await _inputReader.ReadToGrid<Point>();
int total = grid.FindWithValue('X').Sum(p => GetPossibleMatches(grid, p, "XMAS"));
total += grid.FindWithValue('S').Sum(p => GetPossibleMatches(grid, p, "SAMX"));
return total.ToString();
}
//9
//1888
public async Task<string> GetSolutionPart2()
{
//_inputReader.SetSampleInput(true);
Grid<Point> grid = await _inputReader.ReadToGrid<Point>();
int total = grid.FindWithValue('M').Where(p => IsValid(grid, p, 'S')).Count();
total += grid.FindWithValue('S').Where(p => IsValid(grid, p, 'M')).Count();
return total.ToString();
}
private static bool IsValid(Grid<Point> grid, Point p, char otherValue)
{
// validate the bounding box
if (p.X + 3 > grid.Columns || p.Y + 3 > grid.Rows)
{
return false;
}
// check that +1,+1 from the point is A
if (grid.GetNode(p.X + 1, p.Y + 1).Value != 'A')
{
return false;
}
if((grid.GetNode(p.X, p.Y).Value == 'M' && grid.GetNode(p.X + 2, p.Y + 2).Value == 'S' || grid.GetNode(p.X, p.Y).Value == 'S' && grid.GetNode(p.X + 2, p.Y + 2).Value == 'M')
&& (grid.GetNode(p.X, p.Y + 2).Value == 'M' && grid.GetNode(p.X + 2, p.Y).Value == 'S' || grid.GetNode(p.X, p.Y + 2).Value == 'S' && grid.GetNode(p.X + 2, p.Y).Value == 'M'))
return true;
return false;
}
private static int GetPossibleMatches(Grid<Point> grid, Point start, string word)
{
int matches = 0;
bool canLookUp = start.Y + 1 >= word.Length,
canLookForward = grid.Columns - start.X >= word.Length,
canLookDown = grid.Rows - start.Y >= word.Length;
// check up if possible
if (canLookUp && canLookForward && IsMatch(grid, start, -1, 1, word))
{
matches++;
}
if (canLookForward && IsMatch(grid, start, 0, 1, word))
{
matches++;
}
if (canLookForward && canLookDown && IsMatch(grid, start, 1, 1, word))
{
matches++;
}
if (canLookDown && IsMatch(grid, start, 1, 0, word))
{
matches++;
}
return matches;
}
private static bool IsMatch(Grid<Point> grid, Point start, int rowChange, int columnChange, string word)
{
for (int index = 1; index < word.Length; index++)
{
if (grid.GetNode(start.X + (columnChange * index), start.Y + (rowChange * index)).Value != word[index])
return false;
}
return true;
}
}
}