Advent of Code, Day 3

Day 3 of Advent of Code is here! Check out Day 1 for what this is all about.

Did you join my leaderboard? I invite you to join my board, and we can see who can win it ;) Go to “Leaderboard” in the top nav and enter 1030369-e174b794 to join my board.

I have also loaded up the pure code on github, you can follow along there too: pretty pages or the repo.

Spoilers ahead!

I highly encourage you to get through the day’s challenge on your own. I would love to hear how you did though! Did you find a better approach than I did?

Day 3: Toboggan Trajectory

Part I

We have a page with a long list of trees (shown as #)

The definition is as follows: “You start on the open square (.) in the top-left corner and need to reach the bottom (below the bottom-most row on your map). The toboggan can only follow a few specific slopes (you opted for a cheaper model that prefers rational numbers); start by counting all the trees you would encounter for the slope right 3, down 1.” ref

The challenge is to find how many trees we’ll hit following the pattern of moving 3 to the right, then down 1. You’ll note that the data is pretty narrow, and there’s several hundred rows here. The challenge also points out the pattern continues to the right, so each row just repeats to the right as needed.

I opened dev toolbar again, and start by grabbing all of the rows from the page:

var nums = window.document.getElementsByTagName("pre")[0]
nums = nums.innerText.split('\n')

When we work with counters and indexes of arrays, we always have to start with 0. Fortunately, the way this one is spelled out, that actually helps us a lot. The wording is to start at the top left (index 0) and move right 3 (+3) which lands us on 3. If you were to just count as a normal human, you’d be on 4 (1, 2, 3, 4). But data works differently, so we count with 0 first (0, 1, 2, 3).

This one took me a little longer than I wanted. Zero-based counting ALWAYS tricks me. I know it when I go into it, but I always miss something, and have to spend a little more time testing it out to know it’s right.

var columnCounter = 0
var treeCounter = 0
nums.forEach((row, index) => {
    var fullRow = row.repeat(40)
    if(fullRow.substring(columnCounter,columnCounter+1) === '#') {
        console.error('tree hit row:', index, 'column:', columnCounter)
        treeCounter++
    }
    columnCounter += 3
})
console.warn('total trees', treeCounter)

Here’s what I’m doing:

  • Set some variables that will store my counters outside of the loop
  • Loop through all the rows
  • I am using repeat() to pad the amount of data we need to effectively go through all rows.
    • I played around with this number until my total stopped changing. I’m sure there’s a mathematical way of determining the number, but I got a little lazy, that wasn’t the challenge
  • Then we check that position for a tree '#' using substring()
  • If it’s there, I’ve hit a tree, let’s count it
  • Then we move 3 more to the right in columnCounter

Part II

“Time to check the rest of the slopes – you need to minimize the probability of a sudden arboreal stop, after all..” ref

To make things more fun, we’re now adding a few more slopes in the mix. For part 2, we now have 5 slopes to count, and then provide the product of the 5 totals:

Let’s start with our previous function and update it for these new rules

var slopes = [{ right: 1, down: 1 },{ right: 3, down: 1 },{ right: 5, down: 1 },{ right: 7, down: 1 },{ right: 1, down: 2}]
var total = 1
slopes.forEach(slope => {
    var columnCounter = 0
    var treeCounter = 0
    nums.forEach((row, index) => {
        if(index % slope.down === 0) {
            var fullRow = row.repeat(100)
            if(fullRow.substring(columnCounter,columnCounter+1) === '#') {
                treeCounter++
            }
            columnCounter += slope.right
        }
    })
    console.warn('total trees for', slope.right, 'x', slope.down, 'is', treeCounter)
    total *= treeCounter
})
console.warn('total trees', total)

The big changes above include

  • I loaded all the slopes into an array, so I can loop through them. I could’ve just changed the original method for each slope, and then manually add it all up, but that’s not fun
  • We check the remainder, using %, of slope.down value against the row index we’re in. If it’s 0, that means the down divides into the index evenly.
  • We then add the slope.right to the columnCounter
  • Finally we multiply all of the tree totals together
    • Note, I set total to be 1 not 0. Normally, for a counter, you’d start with a zero, since you’re going to increment the value. With a multiplier, if you start with a zero, you’ll always get a zero. My kids just learned this (thanks remote learning): anything times zero is always zero.

How did you do?

How did you find the answer on your own? How did you do it? I’d love to hear how you did! Please comment below!

Series Navigation<< Advent of Code, Day 4Advent of Code, Day 2 >>

Leave a Reply

Up ↑

%d bloggers like this: