--- Day 23: Planting ---

December 23

Listening to: Video Game Study Lounge


It's the day after Christmas. It was a nice day, I had some friends over, we drank eggnog and watch dumb movies. It was a good time. Now to relax, by spending who knows how many hours trying to solve some of these puzzles.


This looks oddly familiar to something like the Game of Life. But it seems pretty straightforward overall. I'm imagining something that would take three passes over a 2d char array:

  1. Add any additional space around the field if necessary
  2. Record each elf that proposes to move - a map of pair, vector<pair>, with the key being the proposed location
  3. Perform the move for any key that has only one proposed move
  4. If any elves moved, or were blocked, repeat

It'll be a bit more complex with having to cycle out which directions are considered in what order, but not too bad overall.

#define COORD pair<int, int>
#define MOVE_LIST map<COORD, vector<COORD>>

// ...

do {
    blocked = 0;
    moves = MOVE_LIST();

    /// Record move proposals
    for (int row = 1; row < field.size()-1; row++)
    for (int col = 1; col < field[0].size()-1; col++)
    {
        // Elf Check
        if (field[row][col] == '.') continue;

        // Clear check
        bool clear = true;
        for (int i = -1; i <= 1; i++)
        for (int j = -1; j <= 1; j++)
        {
            if (i == 0 && j == 0) continue;
            if (field[row+i][col+j] == '#')
            {
                clear = false;
                break;
            }
        }
        if (clear) continue;
        
        // Move proposal
        bool canMove = false;
        for (char d: dirs)
        {
            if (canMove) break;
            switch(d)
            {
                case 'N':
                    if (   field[row-1][col-1] == '.'
                        && field[row-1][col  ] == '.'
                        && field[row-1][col+1] == '.')
                        {
                            moves[COORD(row-1, col)].push_back(COORD(row, col));
                            canMove = true;
                        }
                    break;

                case 'S': // Check South
                case 'E': // Check East
                case 'W': // Check West    
            }
        }

        if (!canMove) blocked++;
    }
    rotate(dirs.begin(), dirs.begin()+1, dirs.end());

    /// Perform moves
    for (auto proposal: moves)
    {
        if (proposal.second.size() > 1) continue;
        field[proposal.first.first][proposal.first.second] = '#';
        field[proposal.second[0].first][proposal.second[0].second] = '.';
    }

} while (++iterations < 10);

This works pretty quickly and reliably!


The second part makes sense - just keep running the simulation until the elves no longer need to move around. Just a few modifications to print out the number of iterations, let it run for a minute or two, and it works just as well.

In retrospect, maybe I would have done better converting this all to a vector<bool> or something instead of messing with strings. But eh, it still ran quick enough.


Time taken: 1 hour 5 minutes

My solutions for today's puzzles