240 lines
10 KiB
C#
240 lines
10 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection.Emit;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace Advent24
|
|
{
|
|
internal class Day4
|
|
{
|
|
public Day4()
|
|
{
|
|
string fileData = System.IO.File.ReadAllText(@"..\..\..\inputd4.txt");
|
|
|
|
// get width of line to be able to navigate the text block in
|
|
// both dimensions
|
|
Int32 textWidth = fileData.IndexOf('\n');
|
|
|
|
Int32 linearPosition = 0;
|
|
|
|
Int32 numberOfXmases = 0;
|
|
|
|
Boolean activatePart2 = true;
|
|
|
|
Int32 numberOfX_mases = 0;
|
|
|
|
Boolean rightBoundaryCheck, leftBoundaryCheck,
|
|
topBoundaryCheck, bottomBoundaryCheck,
|
|
bottomRightBoundaryCheck, topRightBoundaryCheck,
|
|
bottomLeftBoundaryCheck, topLeftBoundaryCheck;
|
|
|
|
if (activatePart2)
|
|
// Find the 'A' starting from where we are currently positioned
|
|
linearPosition = fileData.IndexOf('A', linearPosition);
|
|
else
|
|
// Find the 'X' starting from where we are currently positioned
|
|
linearPosition = fileData.IndexOf('X', linearPosition);
|
|
|
|
while (linearPosition < fileData.Length && linearPosition != -1)
|
|
{
|
|
Console.WriteLine("linearPosition = {0:d}", linearPosition);
|
|
|
|
if (activatePart2)
|
|
// check that we're at least 2 away from the right boundary
|
|
rightBoundaryCheck = (fileData.IndexOf('\n', linearPosition) - linearPosition) > 1;
|
|
else
|
|
// check that we're at least 4 away from the right boundary
|
|
rightBoundaryCheck = (fileData.IndexOf('\n', linearPosition) - linearPosition) > 3;
|
|
|
|
if (activatePart2)
|
|
// check that we're at least 2 away from the left boundary
|
|
leftBoundaryCheck =
|
|
fileData.LastIndexOf('\n', linearPosition) == -1 ? // first line
|
|
(linearPosition >= 1) :
|
|
(linearPosition - fileData.LastIndexOf('\n', linearPosition)) > 1;
|
|
else
|
|
// check that we're at least 4 away from the left boundary
|
|
leftBoundaryCheck =
|
|
fileData.LastIndexOf('\n', linearPosition) == -1 ? // first line
|
|
(linearPosition >= 3) :
|
|
(linearPosition - fileData.LastIndexOf('\n', linearPosition)) > 3;
|
|
|
|
if (activatePart2)
|
|
// check that we're at least 2 away from the top boundary
|
|
topBoundaryCheck = (linearPosition - (textWidth+1)*1) >= 0;
|
|
else
|
|
// check that we're at least 4 away from the top boundary
|
|
topBoundaryCheck = (linearPosition - (textWidth+1)*3) >= 0;
|
|
|
|
if (activatePart2)
|
|
// check that we're at least 2 away from the bottom boundary
|
|
bottomBoundaryCheck = (linearPosition + (textWidth + 1) * 1) < fileData.Length;
|
|
else
|
|
// check that we're at least 4 away from the bottom boundary
|
|
bottomBoundaryCheck = (linearPosition + (textWidth+1)*3) < fileData.Length;
|
|
|
|
// check that we're at least 2 (part2) / 4 (part1) away from the bottom-right boundary
|
|
bottomRightBoundaryCheck = bottomBoundaryCheck && rightBoundaryCheck;
|
|
|
|
// check that we're at least 2 (part2) / 4 (part1) away from the top-right boundary
|
|
topRightBoundaryCheck = topBoundaryCheck && rightBoundaryCheck;
|
|
|
|
// check that we're at least 2 (part2) / 4 (part1) away from the bottom-left boundary
|
|
bottomLeftBoundaryCheck = bottomBoundaryCheck && leftBoundaryCheck;
|
|
|
|
// check that we're at least 2 (part2) / 4 (part1) away from the top-left boundary
|
|
topLeftBoundaryCheck = topBoundaryCheck && leftBoundaryCheck;
|
|
|
|
if (activatePart2)
|
|
{
|
|
// check corner boundaries
|
|
if (
|
|
topRightBoundaryCheck && topLeftBoundaryCheck &&
|
|
bottomRightBoundaryCheck && bottomLeftBoundaryCheck
|
|
)
|
|
{
|
|
if (
|
|
// check bottom-right and top-left diagonal
|
|
(
|
|
(
|
|
fileData[linearPosition + (textWidth + 1) + 1] == 'S' &&
|
|
fileData[linearPosition - (textWidth + 1) - 1] == 'M'
|
|
) ||
|
|
(
|
|
fileData[linearPosition + (textWidth + 1) + 1] == 'M' &&
|
|
fileData[linearPosition - (textWidth + 1) - 1] == 'S'
|
|
)
|
|
) &&
|
|
// check bottom-left and top-right diagonal
|
|
(
|
|
(
|
|
fileData[linearPosition + (textWidth + 1) - 1] == 'S' &&
|
|
fileData[linearPosition - (textWidth + 1) + 1] == 'M'
|
|
) ||
|
|
(
|
|
fileData[linearPosition + (textWidth + 1) - 1] == 'M' &&
|
|
fileData[linearPosition - (textWidth + 1) + 1] == 'S'
|
|
)
|
|
)
|
|
)
|
|
numberOfX_mases++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// check right characters
|
|
if (rightBoundaryCheck)
|
|
{
|
|
if (
|
|
fileData[linearPosition + 1] == 'M' &&
|
|
fileData[linearPosition + 2] == 'A' &&
|
|
fileData[linearPosition + 3] == 'S'
|
|
)
|
|
numberOfXmases++;
|
|
}
|
|
|
|
// check left characters
|
|
if (leftBoundaryCheck)
|
|
{
|
|
if (
|
|
fileData[linearPosition - 1] == 'M' &&
|
|
fileData[linearPosition - 2] == 'A' &&
|
|
fileData[linearPosition - 3] == 'S'
|
|
)
|
|
numberOfXmases++;
|
|
}
|
|
|
|
// check upward characters
|
|
if (topBoundaryCheck)
|
|
{
|
|
if (
|
|
fileData[linearPosition - (textWidth + 1)] == 'M' &&
|
|
fileData[linearPosition - (textWidth + 1) * 2] == 'A' &&
|
|
fileData[linearPosition - (textWidth + 1) * 3] == 'S'
|
|
)
|
|
numberOfXmases++;
|
|
}
|
|
|
|
// check downward characters
|
|
if (bottomBoundaryCheck)
|
|
{
|
|
if (
|
|
fileData[linearPosition + (textWidth + 1)] == 'M' &&
|
|
fileData[linearPosition + (textWidth + 1) * 2] == 'A' &&
|
|
fileData[linearPosition + (textWidth + 1) * 3] == 'S'
|
|
)
|
|
numberOfXmases++;
|
|
}
|
|
|
|
// check bottom-right diagonal characters
|
|
if (bottomRightBoundaryCheck)
|
|
{
|
|
if (
|
|
fileData[linearPosition + (textWidth + 1) + 1] == 'M' &&
|
|
fileData[linearPosition + (textWidth + 1) * 2 + 2] == 'A' &&
|
|
fileData[linearPosition + (textWidth + 1) * 3 + 3] == 'S'
|
|
)
|
|
numberOfXmases++;
|
|
}
|
|
|
|
// check top-right diagonal characters
|
|
if (topRightBoundaryCheck)
|
|
{
|
|
if (
|
|
fileData[linearPosition - (textWidth + 1) + 1] == 'M' &&
|
|
fileData[linearPosition - (textWidth + 1) * 2 + 2] == 'A' &&
|
|
fileData[linearPosition - (textWidth + 1) * 3 + 3] == 'S'
|
|
)
|
|
numberOfXmases++;
|
|
}
|
|
|
|
// check bottom-left diagonal characters
|
|
if (bottomLeftBoundaryCheck)
|
|
{
|
|
if (
|
|
fileData[linearPosition + (textWidth + 1) - 1] == 'M' &&
|
|
fileData[linearPosition + (textWidth + 1) * 2 - 2] == 'A' &&
|
|
fileData[linearPosition + (textWidth + 1) * 3 - 3] == 'S'
|
|
)
|
|
numberOfXmases++;
|
|
}
|
|
|
|
// check top-left diagonal characters
|
|
if (topLeftBoundaryCheck)
|
|
{
|
|
if (
|
|
fileData[linearPosition - (textWidth + 1) - 1] == 'M' &&
|
|
fileData[linearPosition - (textWidth + 1) * 2 - 2] == 'A' &&
|
|
fileData[linearPosition - (textWidth + 1) * 3 - 3] == 'S'
|
|
)
|
|
numberOfXmases++;
|
|
}
|
|
}
|
|
|
|
// increment linear position to start the search again
|
|
// from the next character
|
|
linearPosition++;
|
|
|
|
if (activatePart2)
|
|
// Find the 'A' starting from our updated linear position
|
|
linearPosition = fileData.IndexOf('A', linearPosition);
|
|
else
|
|
// Find the 'X' starting from our updated linear position
|
|
linearPosition = fileData.IndexOf('X', linearPosition);
|
|
}
|
|
|
|
if (activatePart2)
|
|
Console.WriteLine("numberOfX_mases = {0:d}", numberOfX_mases);
|
|
else
|
|
Console.WriteLine("numberOfXmases = {0:d}", numberOfXmases);
|
|
|
|
|
|
// to keep the console window from closing
|
|
Console.ReadKey();
|
|
}
|
|
}
|
|
}
|