--- Day 9: Rope Bridge ---

December 9

Listening to: TUBULAR BELLS


New job is going well! I feel like I'm starting to understand things in this massive, massive codebase I'm entering in to. Getting along with my team well.

I feel like this sort of stuff should go into my actual blog, and not these random blurbs that are before the thing? It's starting to feel like those recipies you find that are paragraphs of someone's random life story before getting into the actual cooking five paragraphs in.


Rope physics! ... kinda.

The problem and the story involved seem kinda.... contrived? Forced? Not sure the right word.

Either way, the problem is kind of interesting at least. Basically something following (but not tracing) the path of another more directly controlled object. The way I see it there's two reasonable ways of tackling this:

  1. Simulate a grid; move the head (and tail when) necessary, marking spaces as needed; count up the '#' of each
  2. Simulate only grid positions, inputing any changed position into a set. Return the size of the set.

The first would make it easier to see what's going on in the middle of it, but the second might be simpler in the long run. So I'll go with that. Besides, the full input has 2000 moves, and I don't necessarily know how large the grid is going to be.

set<pair<int, int>> visited;
int hx, hy, tx, ty;
for (int i = 0; i < steps; i++)
{
    // Move Head
    switch (dir)
    {
        case 'R': hy += 1; break;
        case 'L': hy -= 1; break;
        case 'U': hx += 1; break;
        case 'D': hx -= 1; break;
    }

    // Move Tail if necessary
    if (!cellsAdjacent(hx, hy, tx, ty))
    {
        switch (dir)
        {
            case 'R': tx = hx; ty += 1; break;
            case 'L': tx = hx; ty -= 1; break;
            case 'U': ty = hy; tx += 1; break;
            case 'D': ty = hy; tx -= 1; break;
        }
    }
    visited.insert(pair<int, int>(tx, ty));
}

cellsAdjacent() simply returns if the two cells are cardinally/diagonally adjacent to each other.


Ahahaaha, of course it would do this. I should have seen this. Luckily I chose the second solution, so I just need to essentially add an extra for loop to extend some of this functionality, it looks like I wrote it easily enough that I didn't need to split stuff out. Just deal with more pairs instead of explicitly defined ints for each knot.

I had to fiddle with the 'move remaining knots' section as I couldn't just make assumptions about movement direction anymore; direciton was fiddly.

// Move remaining knots
for (int j = 1; j < NUM_KNOTS; j++)
{
    if (cellsAdjacent(knots[j-1], knots[j])) break;
    
    if (knots[j-1].first  > knots[j].first ) knots[j].first++;
    if (knots[j-1].first  < knots[j].first ) knots[j].first--;
    if (knots[j-1].second > knots[j].second) knots[j].second++;
    if (knots[j-1].second < knots[j].second) knots[j].second--;
}

I've loved the early return pattern ever since I've heard of it. It makes code so much cleaner.


Time taken: 1 hour 15 minutes

My solutions for today's puzzles