2023-12-03 15:45:47 -05:00

122 lines
4.0 KiB
C#

namespace day3;
public class Day3
{
private int _rows;
private int _columns;
private char[][] _grid;
public Day3(string fileContents)
{
var lines = fileContents.Split(Environment.NewLine);
_grid = lines.Select(line => line.ToCharArray()).ToArray();
_rows = _grid.Length;
_columns = _grid[0].Length;
}
private bool _isCharacterASymbol(char c) {
return !char.IsDigit(c) && c != '.';
}
private bool _isSymbolInSurroundingLocation(int i, int j)
{
var foundSymbol = false;
for (var ii = i - 1; ii <= i + 1; ii++)
{
for (var jj = j - 1; jj <= j + 1; jj++)
{
if (ii >= 0 && jj >= 0 && ii < _rows && jj < _columns) {
foundSymbol |= _isCharacterASymbol(_grid[ii][jj]);
}
}
}
return foundSymbol;
}
private IEnumerable<MachinePart> _getSurroundingMachineParts(int i, int j, IList<MachinePart> machineParts)
{
return machineParts.Where(machinePart => machinePart.Locations.Aggregate(false, (hasBeenFound, currentPoint) => {
var differenceRow = Math.Abs(i - currentPoint.Item1);
var differenceCol = Math.Abs(j - currentPoint.Item2);
return hasBeenFound || (!(differenceRow == 0 && differenceCol == 0) && differenceRow <= 1 && differenceCol <= 1);
}));
}
private IList<MachinePart> _getAllMachinePartsInGrid()
{
var machinePartsList = new List<MachinePart>();
int currentlyParsedNumber = 0;
var locations = new List<(int, int)>();
bool isSymbolFound = false;
// We want to iterate over every cell
for (int i = 0; i < _rows; i++)
{
for (int j = 0; j < _columns; j++)
{
var cellContents = _grid[i][j];
if (char.IsDigit(cellContents))
{
// Check the surroundings for a symbol
isSymbolFound |= _isSymbolInSurroundingLocation(i, j);
locations.Add((i, j));
currentlyParsedNumber = (currentlyParsedNumber * 10) + int.Parse(cellContents.ToString());
}
// Check if we are done scanning the number (i.e. at the end of a row or we find a non-integer)
if (!char.IsDigit(cellContents) || j == _columns - 1)
{
if (isSymbolFound)
{
machinePartsList.Add(new MachinePart {
Id = machinePartsList.Count,
Value = currentlyParsedNumber,
Locations = locations
});
}
locations = new List<(int, int)>();
currentlyParsedNumber = 0;
isSymbolFound = false;
}
}
}
return machinePartsList;
}
public int PartOne()
{
var machinePartsList = _getAllMachinePartsInGrid();
return machinePartsList.Aggregate(0, (total, current) => total + current.Value);
}
public long PartTwo()
{
var machinePartsList = _getAllMachinePartsInGrid();
var runningTotal = 0L;
// We are going to do a scan for all gears
for (int i = 0; i < _rows; i++)
{
for (int j = 0; j < _columns; j++)
{
var cellContents = _grid[i][j];
if (cellContents == '*')
{
var surroundingMachineParts = _getSurroundingMachineParts(i, j, machinePartsList);
var numberOfSurroundingMachingParts = surroundingMachineParts.Count();
if (numberOfSurroundingMachingParts == 2) {
runningTotal += surroundingMachineParts.Aggregate(1, (currentRatio, machinePart) => currentRatio * machinePart.Value);
}
}
}
}
return runningTotal;
}
}