DEV Community

Cover image for Treetop Tree House
Robert Mion
Robert Mion

Posted on

Treetop Tree House

Advent of Code 2022 Day 8

Part 1

  1. Analyzing each cross-section
  2. My algorithm in pseudocode
  3. My algorithm in JavaScript

Analyzing each cross-section

Given a grid of trees:

. . . . . . . . . . . . . . . . . . . . . . . . . 
Enter fullscreen mode Exit fullscreen mode

Knowing that all trees on the edge are fine:

* * * * * * . . . * * . . . * * . . . * * * * * * 
Enter fullscreen mode Exit fullscreen mode

For each non-edge tree - for example, the center tree:

. . . . . . . . . . . . ? . . . . . . . . . . . . 
Enter fullscreen mode Exit fullscreen mode

I need to separately analyze each slice of its cross-section:

. . 1 . . . . 1 . . 4 4 ? 2 2 . . 3 . . . . 3 . . 
Enter fullscreen mode Exit fullscreen mode

As long as all values in any slice are less than the source tree, I can consider it visible like the ones on the edge.

How might I do this programmatically?

My algorithm in pseudocode

Iterating through all non-edge trees in the grid:

Track the amount of trees visible - accounting for all edge trees For each tree from the second row to the second-to-last For each tree from the second column to the second-to-last Set flag to false Set directions to a 4-element array of relative (x,y) coordinates Set index to 0 While flag is false and index is less than the length of directions Generate a list of values originating from the current tree in a straight line stepping in the direction of the relative coordinate at the current index If the maximum value in the list is less than the current tree's value Set flag to true Else Increment index by 1 If flag is true Increment the amount of trees visible by 1 Else Don't increment the amount of trees visible Return the amount of trees visible 
Enter fullscreen mode Exit fullscreen mode

I wonder how close this will end up being to my actual algorithm.

Here I go!

My algorithm in JavaScript

  • It very closely matches my pseudocode
  • The bulk of it is the part where I walk each slice of the cross-section
let grid = input .split('\n') .map(row => row.split('').map(Number)) let answer = grid.length * 4 - 4 for (let row = 1; row < grid.length - 1; row++) { for (let col = 1; col < grid[row].length - 1; col++) { let flag = false let index = 0 let coords = [[-1,0],[0,1],[1,0],[0,-1]] while (!flag && index < coords.length) { let slice = [] let y = row + coords[index][0] let x = col + coords[index][1] while ( (y >= 0 && y < grid.length) && (x >= 0 && x < grid[y].length) ) { slice.push(grid[y][x]) y += coords[index][0] x += coords[index][1] } if (Math.max(...slice) < grid[row][col]) { flag = true } index++ } if (flag) answer++ } } return answer 
Enter fullscreen mode Exit fullscreen mode

Part 2

  1. Enter: more careful analysis of each tree
  2. My algorithm in JavaScript

Enter: more careful analysis of each tree

  • It's no longer enough to spot a tree of equal or greater height
  • My algorithm from Part 1 seems well set to adjust to this new requirement of checking nearby trees

My algorithm in JavaScript

  • I start both for loops at 0 instead of 1 to check every tree
  • I track fewer variables inside the inner for loop
  • I added a third condition to the while loop that causes it to break as soon as a number equal to or higher than the current tree is discovered
let grid = input .split('\n') .map(row => row.split('').map(Number)) let answer = 0 for (let row = 0; row < grid.length; row++) { for (let col = 0; col < grid[row].length; col++) { let coords = [[-1,0],[0,1],[1,0],[0,-1]] let scores = coords.map(coord => { let slice = [] let y = row + coord[0] let x = col + coord[1] while ( (y >= 0 && y < grid.length) && (x >= 0 && x < grid[y].length) && (slice[slice.length - 1] || 0) < grid[row][col] ) { slice.push(grid[y][x]) y += coord[0] x += coord[1] } return slice.length }) let product = scores.reduce((sum, score) => sum * score) answer = product > answer? product : answer } } return answer 
Enter fullscreen mode Exit fullscreen mode

I got confused when writing this bit of code:

(slice[slice.length - 1] || 0) 
Enter fullscreen mode Exit fullscreen mode

It is designed to account for an empty list whose length would be 0 and therefore would not have an item at index -1.

I did it!!

  • I solved both parts!
  • By using several nested for and while loops!
  • Along with some map() and reduce()!

This ended up being a delightfully challenging twist on the now-common grid-themed puzzle!

I'm very glad I have accrued all my skills working with this type of puzzle from similar puzzles in years past.

It made solving this one much easier: I could focus on other parts of the problem...besides relative coordinates!

Top comments (0)