107 lines
3.4 KiB
C#
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;
|
|
}
|
|
}
|
|
} |