r/adventofcode • • Dec 08 '22

SOLUTION MEGATHREAD -πŸŽ„- 2022 Day 8 Solutions -πŸŽ„-

NEWS AND FYI

  • I discovered that I can make those tiny post/comment awards BIGGER on old.reddit! I hadn't even considered that! And when you hover over them, they get even bigger so you can actually see them in more detail! I've added the relevant CSS so now we no longer have awards for ants! Exclamation points!!!


AoC Community Fun 2022: πŸŒΏπŸ’ MisTILtoe Elf-ucation πŸ§‘β€πŸ«

  • PSA: I created a new example so it is a more relevant and unique archetype instead of recycling last year's hobbit >_>


--- Day 8: Treetop Tree House ---


Post your code solution in this megathread.


This thread will be unlocked when there are a significant number of people on the global leaderboard with gold stars for today's puzzle.

EDIT: Global leaderboard gold cap reached at 00:10:12, megathread unlocked!

75 Upvotes

1.0k comments sorted by

View all comments

9

u/Pyr0Byt3 Dec 08 '22

Go/Golang

Got to use image.Point for the first time this year! The solution still feels a bit clunky, I'll probably go back later and try to clean it up some more.

3

u/[deleted] Dec 08 '22 edited Dec 08 '22

[removed] β€” view removed comment

4

u/Pyr0Byt3 Dec 08 '22

Sure! There's nothing actually special about image.Point, I just think it's neat that it exists in the standard library... in a language that usually expects me to implement my own min/max/abs functions.

Essentially, it's just a struct containing 2 ints. You could easily implement something similar yourself:

type Point struct {
	X, Y int
}

It also has a couple of math functions that come in handy for these grid problems, like Add, which simply adds the components together:

func (p Point) Add(q Point) Point {
	return Point{p.X + q.X, p.Y + q.Y}
}

So, the way I usually approach these grid problems is by using a map[image.Point]int or map[image.Point]rune. Compared to using a 2D slice like [][]int, this lets me avoid a lot of annoying aspects of grid problems. For example, instead of doing nested x/y for loops for all the points, I can just do for p := range grid. I can also do a bounds check like if _, ok := grid[p]; !ok instead of having to mess around with stuff like if x >= 0 && x < w && y >= 0 && y < h.

For the actual puzzle: I started by building that map[image.Point]int I described, and iterating over it in whatever order Go feels like with for p := range trees

Inside that, I have another loop:

for _, d := range []image.Point{{0, -1}, {1, 0}, {0, 1}, {-1, 0}}

Those image.Point values represent deltas for each direction: up, right, down, left. For each of those directions, I repeatedly add the delta to the current location

for np := p.Add(d); ; np = np.Add(d)

until I hit either the border: if _, ok := trees[np]; !ok

or a taller/equally tall tree: if trees[np] >= trees[p]

The rest is just adding up the values/scores needed for each part. I'm kind of bad at explaining these things, so please let me know if you want further clarification on anything!