Advent of Code: 5 mins 1 Bomb Solution: Day 3

Christmas Gifts

Overview

Does everyday just get easier? Maybe It’s just me, but I feel like the first day was the most conceptually challenging so far.

Today’s answer is written in python! Was feeling a little lazy with the type safety of swift and wanted to ride down 81 on a motorcycle on fire instead (if you went to VT you know that opening from 2505 πŸ˜‚)

Enough chatter, let’s get into Day 3 of Advent of code 🍺 πŸŽ„ πŸŽ…


Problem Statement

Part 1)

“Due to the local geology, trees in this area only grow on exact integer coordinates in a grid. You make a map (your puzzle input) of the open squares (.) and trees (#) you can see. For example:

..##.......
#...#...#..
.#....#..#.
..#.#...#.#
.#...##..#.
..#.##.....
.#.#.#....#
.#........#
#.##...#...
#...##....#
.#..#...#.#

These aren’t the only trees, though; due to something you read about once involving arboreal genetics and biome stability, the same pattern repeats to the right many times:

..##.........##.........##.........##.........##.........##.......  --->
#...#...#..#...#...#..#...#...#..#...#...#..#...#...#..#...#...#..
.#....#..#..#....#..#..#....#..#..#....#..#..#....#..#..#....#..#.
..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#
.#...##..#..#...##..#..#...##..#..#...##..#..#...##..#..#...##..#.
..#.##.......#.##.......#.##.......#.##.......#.##.......#.##.....  --->
.#.#.#....#.#.#.#....#.#.#.#....#.#.#.#....#.#.#.#....#.#.#.#....#
.#........#.#........#.#........#.#........#.#........#.#........#
#.##...#...#.##...#...#.##...#...#.##...#...#.##...#...#.##...#...
#...##....##...##....##...##....##...##....##...##....##...##....#
.#..#...#.#.#..#...#.#.#..#...#.#.#..#...#.#.#..#...#.#.#..#...#.#  --->

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

part 2)

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

Determine the number of trees you would encounter if, for each of the following slopes, you start at the top-left corner and traverse the map all the way to the bottom:

  • Right 1, down 1.
  • Right 3, down 1. (This is the slope you already checked.)
  • Right 5, down 1.
  • Right 7, down 1.
  • Right 1, down 2.

In the above example, these slopes would find 2734, and 2 tree(s) respectively; multiplied together, these produce the answer 336.

What do you get if you multiply together the number of trees encountered on each of the listed slopes?


Problem Requirement List

Let’s break down the requirements list for both problems and then see if we can architect a solution that will allow us to reuse as much code as possible between the problems … Since we’re checking the rest of the slopes, I don’t think this will be a problem 🍻

Part 1 requirements:

  • Read in the map and create a map for Santa to traverse
  • Place Santa in the top right corner of the map (0,0)
  • Move Santa until we fall off the BOTTOM of the map
    • count each position that Santa lands on which has a tree
  • Return the number of trees he ran into

As you can probably tell, the two questions are nearly identical. The only change between them is that we do multiple slopes for the second question. Let’s go ahead and write a solution that will allow us to plug and play any slope and map that we want! That way Santa doesn’t have any trouble flying around the world 🍺 πŸŽ„ πŸŽ…


My Solution

My solution is pretty straightforward. First, I create the map for Santa. All I really do here is read in all of the lines from the input file, iterate over them, and create a 2-D map for Santa by placing a character representing the object at the position in each (row, col) coordinate space.

with open("input.txt) as f:
    topology_map = [[pos for pos in line.strip()] for line in f.readlines()]

Next, I wrote a function that returns the number of trees πŸŽ… runs into given the slope that Santa is using and the map that he’s going to traverse (I sure would hope he had a couple of 🍺 because after running that program, I can tell ya, it’s gonna hurt).

def find_num_trees_on_route(santas_map, slope) -> int:
    """
    slope: tuple of (rise, run)
    santas_map: two dimensional array accessed [row][col]
    """
    TREE = "#"
    trees_encountered = 0
    curr_pos = (0, 0)
    rise, run = slope

    while on_map((curr_pos := (curr_pos[0] + rise, curr_pos[1] + run)), santas_map):
        row, col = curr_pos
        biome_col = col % len(santas_map[0])
        pos_type = santas_map[row][biome_col]
        trees_encountered += 1 if pos_type is TREE else 0

    return trees_encountered

def on_map(pos, santas_map) -> bool:
    return False if pos[0] >= len(santas_map) else True

See how I snuck in that walrus operator? If you don’t know what that is, make sure to check-out my post here explaining what it is and how you can use it in your python code!

Now, all that’s left to do is run the program with the slope that you want! To make it even more fancy for part 2, I wrote a quick function to calculate the tree-encounter-multiplier (does that even make sense?) given a list of slopes. With a little but of functional programming, we can turn that into a one liner!

import operator
from functools import reduce

def tree_slope_multiplier(santas_map, slopes) -> int:
    return reduce(operator.mul, [find_num_trees_on_route(santas_map, slope) for slope in slopes], 1)

Now you can pass in any list of slopes to the tree_slope_multiplier function and get your answer🍻 ! Pretty sweet!


Wrap Up

Hope you enjoyed Day 3 of Advent of Code! I switched it up for you python lovers so I hope that made you happy 🐍

It definitely wasn’t a 2 liner like I thought I would do, but I thought it was pretty clean. You could easily reduce the size of the while loop by directly accessing the tuple index’s in the comparisons, but you will have no idea what your code is doing when you come back to it tomorrow.

Santa was definitely happy with my solution, was he happy with yours? Let me know in the comments ⬇️ if you were able to come up with this solution on your own! I can’t always promise the best complexity (cause I’m not going to cheat) but if you can do better, let me know down below!

As always, if you liked today’s content, make sure you subscribe to the newsletter down below and if you want to support my coffee addiction, help me out by buying me a coffee! It keeps me going to create more AWESOME FREE CONTENT FOR YOU! Thanks for taking the time to unwrap some bytes with me. Cheers! πŸ» πŸŽ„ πŸŽ…

Processing…
Success! You're on the list.

Shoutout to Mel Poole on Unsplash for the awesome photo!

Leave A Comment