--- Day 3: Gearing Up ---

December 3

Listening to: Vinesauce (playing some awful GTA clone)


I'm starting this one a bit late again, but with good reason this time! A friend had an early holiday party at their house last night, and during the day today there was a nice holiday market that me and some friends went to. It was super cozy, plenty of mulled wine and cider, and good vibes all around!


So it looks like this is a 2d map of numbers and symbols, and I have to find which numbers are next to symbols (or rather, not next to symbols). This doesn't seem TOO bad.

I'm consering a 2 pass solution:

  1. Parse out the lines to find the areas with number runs, and make note of them (eg. Line 3, Pos 2-4)
  2. Look in the rectangle around the line for any symbols (eg. search Lines 2-4, Pos 1-5)
struct NumPos {
    int number, line, start, length;
    char symbol;
};

// Pass 1: Find number runs
vector<NumPos*> numbers;
for (int i = 0; i < schematic.size(); i++)
{
    for (int j = 0; j < schematic[i].size(); j++)
    {
        if (isDigit(schematic[i][j]))
        {
            NumPos* numberRun = new NumPos { 0, i, j, 0, ' ' };
            while (j <= schematic[i].size() && isDigit(schematic[i][j]))
            {
                numberRun->number = (numberRun->number * 10) + (schematic[i][j] - '0');
                numberRun->length++;
                j++;
            }
            numbers.push_back(numberRun);
        }
    }
}

// Pass 2: Identify symbols
int schematicHeight = schematic.size();
int schematicWidth = schematic[0].length();
for (NumPos* partNum : numbers)
{
    int startLine = max(partNum->line-1, 0);
    int endLine = min(partNum->line+1, schematicHeight-1);
    int startRun = max(partNum->start-1, 0);
    int endRun = min(partNum->start + partNum->length, schematicWidth-1);

    for (int x = startLine; x <= endLine; x++)
    {
        for (int y = startRun; y <= endRun; y++)
        {
            if (!isDigit(schematic[x][y]) && schematic[x][y] != '.')
            {
                partNum->symbol = schematic[x][y];
            }
        }
    }
}

And from there, just sum up the numbers for everything that has a symbol!


Ugghh.... for part two, I need to look only at one symbol (*), and I need TWO adjacent ones to deal with it. If I had thought of that I might have implented it differently. Luckily I can adjust my current code to add the symbol's location to the struct, then look for pairs of symbols with the same symbol location of *. I can probably just use a map<int, int> for it, without even adjusting the struct... hmm...

map<pair<int, int>, vector<NumPos*>> gears;

// ...

if (schematic[x][y] == '*')
{
    partNum->symbol = schematic[x][y];
    gears[pair<int, int>(x, y)].push_back(partNum);
}

Yep, that was it! Just had to make sure that for every value of gears that had more than 1 value, multiply those values together!

As an aside, it can be distracting try to watch a twitch stream and code at the same time.

I really need to fix the syntax highlighting on this site too... it looks too... bland right now


Time taken: 1 hour

My solutions for today's puzzles