Advent of Code - Day 4

If you can optimize the work the forklifts are doing, maybe they would have time to spare to break through the wall.

Past puzzles have involved some grid traversing so I had a good start on this one. Similar to minesweaper you need to go through the grid and count the neighboring rolls(mines) and if there are fewer than 4 in the surrounding squares that roll can be marked for removal.

Part 1

This part only required doing the evaluation once and returning the number of rolls that can be removed. For most positions within the grid there are eight adjacent positions that need to be checked. I did spend some time doing this the long way, writing out each position that needed to be evaluated.

if grid[r-1][c-1] == "@":
    count += 1
if grid[r-1][c] == "@":
    count += 1
if grid[r][c-1] == "@":
    count += 1            
if grid[r-1][c+1] == "@":
    count += 1
if grid[r][c+1] == "@":
    count += 1
if grid[r+1][c-1] == "@":
    count += 1
if grid[r+1][c] == "@":
    count += 1
if grid[r+1][c+1] == "@":
    count += 1

This of course is the wrong way to do this check but I think it helped me identify the right way if that makes sense. Sometimes I need to do it the wrong way first for some reason.

Instead of identifying all the conditions I do want to check I wrote the following that will go through all of the above and I just needed the specify the one position I did not want to check. Which of course is the position I'm currently on. The other conditions are making sure not to evaluate outside the grid area.

for i in range(r-1,r+2):
    for j in range(c-1, c+2):
        if (i >= 0 and j >= 0) and (i < len(grid) and j < len(grid[r])) and (r != i or c != j):
            if grid[i][j] == "@":
                count += 1

I feel like there has to be a better way to do this but I have the above running in another series of for loops just to go through the grid. As that happens a new grid is being built with "x" replacing any "@" if it can be removed. This way you're not updating a grid as you're traversing. This also helped with part 2.

Part 2

This part basically says repeat part 1 on the new grid until you cannot remove any more rolls. This sounds like a recursive function to me. So that's what I did. I don't know if this is necessary but I added the number of removed rolls to the function call. I decided this function should return the count of removed.

The exit condition for the function is if there are no more rolls to remove. If there are more to be removed the function is called again.

if removable == 0:
    return removed
else:
    removed += removable
    return freeRolls(marked_grid, removed)

For fun I added some print commands and grid updating so the examples provided in the description of the puzzle can be recreated. This just involves updating "x" to "." once the rolls are removed.

With all the printing remove this returns the correct final result in 0.55 seconds. I'm interested to see some better solutions here and will be looking into that after posting this now.

Listening to: Black Pumas - Colors
Tags
Christopher Himes

I'm Christopher Himes (he⁠/⁠him), an accomplished tech professional living in Metro Detroit. I'm currently looking for work as a product owner or developer.

More about me

Comments

This blog uses a Mastodon and webmentions for comments. You can comment by replying on Mastodon/ActivityPub/Fediverse account or webmention.

Recent Posts