I got married a few hours ago. So that's neat.
This seems like a 2d grid puzzle, but the fact that the beams only move downwards betrays the fact that each iteration only really needs to go down one row at a time. So as it's iterating downward, only the list of columns that currently have beams really need to be kept track of; and since beams can be created in the same column, just having a set is enough to keep track of everything.
var (_, col) = Utils.Find2D(Floor, 'S');
var beams = new HashSet<int> { col };
foreach (var row in Floor)
{
foreach (var beam in beams.ToList())
{
if (row[beam] == '^')
{
beams.Remove(beam);
beams.Add(beam + 1);
beams.Add(beam - 1);
}
}
}
For part 2, honestly, this doesn't seem too much more complicated. Since every potential path needs to be accounted for, instead of just recording each current beam's column, also record the count of paths that lead there in the current row.
var (_, startCol) = Utils.Find2D(Floor, 'S');
var beams = new Dictionary<int, long>();
beams[startCol] = 1;
foreach (var row in Floor)
{
foreach (var beam in beams.ToList())
{
var (col, count) = beam;
if (row[col] == '^')
{
if (beams.ContainsKey(col - 1)) beams[col - 1] += count;
else beams[col - 1] = count;
if (beams.ContainsKey(col + 1)) beams[col + 1] += count;
else beams[col + 1] = count;
beams.Remove(col);
}
}
}