Files
advent-of-code/AdventOfCode C#/AOC.Tests/Y2024/Day04.cs
2024-12-05 21:47:47 +00:00

241 lines
7.5 KiB
C#

namespace AOC.Tests.Y2024;
[TestFixture]
[Parallelizable(ParallelScope.All)]
public class Day04
{
[SetUp]
public void Setup()
{
realData = File.ReadAllLines(Path.Combine(TestContext.CurrentContext.TestDirectory, "Y2024", "Data",
$"{GetThisClassName()}.dat"));
}
protected string GetThisClassName() { return GetType().Name; }
private string[] realData;
private bool FindWord(string word, string[] lines, int charNum, int lineNum)
{
// This word search allows words to be horizontal, vertical, diagonal, written backwards, or even overlapping other words.
// Start at the current character (if it matches the first letter in the word) and search in all directions for the next letter in the word.
if (lines[lineNum][charNum] == word[0])
{
Console.WriteLine($"Checking char {charNum}");
try
{
Console.WriteLine("Checking right");
// Check right
if (lines[lineNum].Substring(charNum, word.Length) == word)
{
Console.WriteLine($"Found to right at line: {lineNum} char: {charNum}");
return true;
}
}
catch (Exception ex)
{
// Ignore, probably outside the 3d array
}
try
{
Console.WriteLine("Checking left");
// Check left
if (lines[lineNum].Substring(charNum - (word.Length - 1), word.Length) == new string(word.Reverse().ToArray()))
{
Console.WriteLine($"Found to left at line: {lineNum} char: {charNum}");
return true;
}
}
catch (Exception ex)
{
// Ignore, probably outside the 3d array
}
try
{
Console.WriteLine("Checking up");
// Check up
bool notFoundUpwards = false;
for (int i = 1; i < (word.Length - 1); i++)
{
if ((lineNum - 1) >= 0)
{
try
{
Console.WriteLine(lines[lineNum - i][charNum]);
}
catch (Exception ex)
{
Console.WriteLine($"Error with accessing the char on the line - {ex.Message}");
notFoundUpwards = true;
throw;
}
try
{
Console.WriteLine(word[i]);
}
catch (Exception ex)
{
Console.WriteLine($"Error with accessing the char number {i} in the word - {ex.Message}");
notFoundUpwards = true;
throw;
}
if (lines[lineNum - i][charNum] != word[i])
{
notFoundUpwards = true;
break;
}
}
else
{
notFoundUpwards = true;
}
}
if (!notFoundUpwards)
{
Console.WriteLine($"Found upwards at line: {lineNum} char: {charNum}");
return true;
}
}
catch (Exception ex)
{
// Ignore, probably outside the 3d array
}
try
{
Console.WriteLine("Checking down");
// Check down
bool notFoundDownwards = false;
for (int i = 1; i < (word.Length - 1); i++)
{
if ((lineNum + i) <= lines.Length)
{
try
{
Console.WriteLine(lines[lineNum + i][charNum]);
}
catch (Exception ex)
{
Console.WriteLine($"Error with accessing the char on the line - {ex.Message}");
notFoundDownwards = true;
throw;
}
try
{
Console.WriteLine(word[i]);
}
catch (Exception ex)
{
Console.WriteLine($"Error with accessing the char number {i} in the word - {ex.Message}");
notFoundDownwards = true;
throw;
}
if (lines[lineNum + i][charNum] != word[i])
{
notFoundDownwards = true;
break;
}
}
else
{
notFoundDownwards = true;
}
}
if (!notFoundDownwards)
{
Console.WriteLine($"Found downwards at line: {lineNum} char: {charNum}");
return true;
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
// Ignore, probably outside the 3d array
}
try
{
Console.WriteLine("Checking diagonals");
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
// TODO - diagonals!!
return false;
}
[TestCase(@"..X...X
.SAMX.M
.A..A.A
XMAS.SS
.X.....", 4)]
[TestCase(@"MMMSXXMASM
MSAMXMSMSA
AMXSXMAAMM
MSAMASMSMX
XMASAMXAMM
XXAMMXXAMA
SMSMSASXSS
SAXAMASAAA
MAMMMXMMMM
MXMXAXMASX", 18)]
[TestCase(null, 232)] // The actual answer
public void Part1(string? input, int? expected)
{
// string[] lines = input != null ? new[] { input } : realData;
string[] lines = input != null ? input.Split("\n") : realData;
var result = 0;
foreach (var (line, index) in lines.WithIndex())
{
Console.WriteLine($"=====\nChecking line {index}\n=====");
for (int i = 0; i < line.Length; i++)
{
if (FindWord("XMAS", lines, i, index))
{
result += 1;
}
}
}
if (expected != null)
{
Assert.That(result, Is.EqualTo(expected.Value));
}
Console.WriteLine($"Part 1: {result}");
}
[TestCase("blah", 1)]
[TestCase(null, 1783)] // The actual answer
public void Part2(string? input, int? expected)
{
//string[] lines = input != null ? new[] { input } : realData;
// string[] lines = input != null ? input.Split("\n") : realData;
//if (expected != null)
//{
// Assert.That(result, Is.EqualTo(expected.Value));
//}
//Console.WriteLine($"Part 2: {result}");
}
}