I use VSCode as a my editor/IDE. When I started it up today, it just opened an AI chat pane for... I didn't even read why, I just closed it too quick to really read it. I just saw "AI Chat" and immediately had a bad feeling. I may need to find a new editor.
A grid problem was inevitable, though this one seems easy. At least, part 1 seems easy. Especially since I have some utility functions, particularly to just parse and pad out the floor with some empty spaces.
floor = Utils.Parse2DGrid(input);
Utils.PadGrid(floor, '.');
In fact, may as well write a function to iterate over a 2d grid. Saves a little space and typing, makes it a bit more readable.
int count = 0;
Utils.Iterate2DGrid(floor, rollCount, padding: 1);
void rollCount(int x, int y)
{
if (floor[x][y] != '@') return;
int neighbors = 0;
if (floor[x - 1][y - 1] == '@') neighbors++;
if (floor[x - 1][y] == '@') neighbors++;
if (floor[x - 1][y + 1] == '@') neighbors++;
if (floor[x][y - 1] == '@') neighbors++;
if (floor[x][y + 1] == '@') neighbors++;
if (floor[x + 1][y - 1] == '@') neighbors++;
if (floor[x + 1][y] == '@') neighbors++;
if (floor[x + 1][y + 1] == '@') neighbors++;
if (neighbors < 4) count++;
}
Part 2 doesn't seem much worse. Modify part 1 to also remove the roll when counting, and repeat on the whole floor until there's a full iteration with no furtrher rolls removed.
do
{
count = 0;
Utils.Iterate2DGrid(floor, tryRollRemove, padding: 1);
total += count;
} while (count != 0);
I ended up spending time trying different versions of Util.Iterate2DGrid() until I got a version I liked. I had to include a parameter to also take into account potential padding on a 2d grid to make things a bit easier, since that's what I commonly do on these sorts of "neighbor on a 2d grid" problems. Sometimes it's easier and (computationally) quicker to add begnin data and just iterate from 1,1 than to keep the grid as-is and add checks for all of the edges.
EDIT: This is a day later, and I realized an optimization I could have done after the first pass would be to only check around the spots where a roll was removed last time.
Still ran in 11ms without that optimization though, so it would have traded off memory and extra coding time to do it.