126 lines
3.9 KiB
C#
126 lines
3.9 KiB
C#
using AdvenOfCode.Contracts;
|
|
using AdventOfCode.HelperClasses;
|
|
|
|
namespace AoC_2025;
|
|
|
|
public class Day07 : IPuzzleSolver<long>
|
|
{
|
|
private string[] ParsePuzzleInput(string path)
|
|
{
|
|
var puzzleInput = File.ReadAllLines(path)
|
|
.Where(line => !string.IsNullOrWhiteSpace(line))
|
|
.ToArray();
|
|
return puzzleInput;
|
|
}
|
|
|
|
public long SolvePart1(string pathToPuzzleInput)
|
|
{
|
|
var grid = ParsePuzzleInput(pathToPuzzleInput);
|
|
var start = GetStart(grid);
|
|
var count = TraverseGridAndCountSplitters(grid, start);
|
|
return count;
|
|
}
|
|
|
|
public long SolvePart2(string pathToPuzzleInput)
|
|
{
|
|
var grid = ParsePuzzleInput(pathToPuzzleInput);
|
|
var start = GetStart(grid);
|
|
var timelinesCount = GetTimelinesCountRecursive(grid, start, []);
|
|
return timelinesCount;
|
|
}
|
|
|
|
public long SolvePart2Again(string pathToPuzzleInput)
|
|
{
|
|
var grid = ParsePuzzleInput(pathToPuzzleInput);
|
|
var timelinesCount = GetTimelinesCount(grid);
|
|
return timelinesCount;
|
|
}
|
|
|
|
private Coordinate GetStart(string[] grid)
|
|
{
|
|
return new Coordinate(0, grid[0].IndexOf('S'));
|
|
}
|
|
|
|
private long TraverseGridAndCountSplitters(string[] grid, Coordinate start)
|
|
{
|
|
HashSet<Coordinate> visited = [start];
|
|
var seen = new Queue<Coordinate>();
|
|
seen.Enqueue(start);
|
|
var splittersHit = 0L;
|
|
while (seen.TryDequeue(out var current))
|
|
{
|
|
if (current.X >= grid.Length) continue;
|
|
if (current.Y >= grid[0].Length || current.Y < 0) continue;
|
|
|
|
if (grid[(int)current.X][(int)current.Y] == '^')
|
|
{
|
|
splittersHit++;
|
|
CheckAndEnqueueIfNotVisited(current with {Y = current.Y - 1});
|
|
CheckAndEnqueueIfNotVisited(current with {Y = current.Y + 1});
|
|
}
|
|
else
|
|
{
|
|
CheckAndEnqueueIfNotVisited(current with {X = current.X + 1});
|
|
}
|
|
}
|
|
|
|
return splittersHit;
|
|
|
|
void CheckAndEnqueueIfNotVisited(Coordinate coordinate)
|
|
{
|
|
if (visited.Add(coordinate)) seen.Enqueue(coordinate);
|
|
}
|
|
}
|
|
|
|
// Dictionary only for memoization
|
|
private long GetTimelinesCountRecursive(string[] grid, Coordinate current, Dictionary<Coordinate, long> memory)
|
|
{
|
|
if (current.X >= grid.Length)
|
|
{
|
|
return 1;
|
|
}
|
|
if(memory.TryGetValue(current, out var count)) return count;
|
|
|
|
if (grid[(int)current.X][(int)current.Y] == '^')
|
|
{
|
|
var resLeft = GetTimelinesCountRecursive(grid, current with {Y = current.Y - 1}, memory);
|
|
var resRight = GetTimelinesCountRecursive(grid, current with {Y = current.Y + 1}, memory);
|
|
memory[current] = resLeft + resRight;
|
|
return resLeft + resRight;
|
|
}
|
|
|
|
var res = GetTimelinesCountRecursive(grid, current with {X = current.X + 1}, memory);
|
|
memory[current] = res;
|
|
return res;
|
|
}
|
|
|
|
private long GetTimelinesCount(string[] grid)
|
|
{
|
|
var numbersGrid = grid
|
|
.Select(line => line.Select(c => 0L).ToArray())
|
|
.ToArray();
|
|
|
|
for (var x = 1; x < numbersGrid.Length; x++)
|
|
{
|
|
for (var y = 0; y < numbersGrid[x].Length; y++)
|
|
{
|
|
var gridValue = grid[x - 1][y];
|
|
switch (gridValue)
|
|
{
|
|
case 'S':
|
|
numbersGrid[x][y] = 1;
|
|
break;
|
|
case '.':
|
|
numbersGrid[x][y] += numbersGrid[x - 1][y];
|
|
break;
|
|
case '^':
|
|
numbersGrid[x][y - 1] += numbersGrid[x - 1][y];
|
|
numbersGrid[x][y + 1] += numbersGrid[x - 1][y];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return numbersGrid[^1].Sum();
|
|
}
|
|
} |