Categories

# The Advent of Code is coming in a few days!

We’re only a few days from December, which means it will soon be time for the great programming exercise known as the Advent of Code!

Think of it as an Advent calendar, but chocolates (or cheese, or wine), you’re presented with a new programming puzzle every day between the start of December and Christmas Day, in which you try to save Santa’s mission. You can use whatever programming language you want, and you don’t need to be an expert — as the site says, “just a little programming knowledge and some problem solving skills will get you pretty far.”

Advent of Code started in 2015, and has been taking place every year ever since. The 2020 edition begins on Tuesday, December 1st at 12:00 midnight Eastern time (UTC-5).

Not only do I plan on participating in this year’s Advent of Code, but I might even use a couple of the challenges in the Python class I’m currently teaching on behalf of Computer Coach.

## Solving Advent of Code 2019’s day one challenge

Here’s the premise of the 2019 Advent of Code’s challenges: Santa is stuck at the edge of the solar system, and you have to rescue him. Each day’s challenge, which has two parts, gets you closer to bringing him home and saving Christmas.

### Day one challenge, part one

Here’s the first part of day one’s challenge:

The Elves quickly load you into a spacecraft and prepare to launch.

At the first Go / No Go poll, every Elf is Go until the Fuel Counter-Upper. They haven’t determined the amount of fuel required yet.

Fuel required to launch a given module is based on its mass. Specifically, to find the fuel required for a module, take its mass, divide by three, round down, and subtract 2.

For example:

• For a mass of `12`, divide by 3 and round down to get `4`, then subtract 2 to get `2`.
• For a mass of `14`, dividing by 3 and rounding down still yields `4`, so the fuel required is also `2`.
• For a mass of `1969`, the fuel required is `654`.
• For a mass of `100756`, the fuel required is `33583`.

The Fuel Counter-Upper needs to know the total fuel requirement. To find it, individually calculate the fuel needed for the mass of each module (your puzzle input), then add together all the fuel values.

What is the sum of the fuel requirements for all of the modules on your spacecraft?

While the problems in the Advent of Code are the same for every participant, the data for each participant is different (there’s a sign-up process, which gives you an account, your own progress tracker, and your own data). This prevents participants from simply sharing the solution.

Here are the module masses that were provided for my account:

I decided to use the Python REPL to tackle this problem.

My first step was to copy the numbers above, paste them into a triple-quoted string, and assign that string to the variable `raw_input`:

Now that I had the data in a string, I could split the string into an array, using the newline character as the delimiter. I named the array `split_input`:

`split_input` is an array of strings which needed to be converted into integer values.

In many other languages, I’d do this by using the `map` function to apply a “convert a string to its integer value” function to every item in the array, creating a resulting array called `masses`. Here’s the Python version of that approach:

It works, but from a Python programming point of view, it just doesn’t feel right.

The Pythonic approach would involve using a list comprehension instead of `map` (and then using the resulting iterator into a list). It just seems more readable:

Once I had the masses, I could then calculate the fuel requirements for each mass. This may be the only time I’ve ever made use of Python’s floor division operator, which performs an integer division, rounding down:

The map/list/lambda approach works just fine, but once again, a list comprehension just seems more elegant to my eye:

And now that I had the fuel requirements for each module, all I had to do was get their sum:

I entered the value for total_fuel into the solution text field, and Advent of Code immediately told me that I had solved part one of the day one challenge! So far, so good.

### Day one challenge, part two

Part two of the challenge was a refinement of part one:

During the second Go / No Go poll, the Elf in charge of the Rocket Equation Double-Checker stops the launch sequence. Apparently, you forgot to include additional fuel for the fuel you just added.

Fuel itself requires fuel just like a module – take its mass, divide by three, round down, and subtract 2. However, that fuel also requires fuel, and that fuel requires fuel, and so on. Any mass that would require negative fuel should instead be treated as if it requires zero fuel; the remaining mass, if any, is instead handled by wishing really hard, which has no mass and is outside the scope of this calculation.

So, for each module mass, calculate its fuel and add it to the total. Then, treat the fuel amount you just calculated as the input mass and repeat the process, continuing until a fuel requirement is zero or negative. For example:

• A module of mass `14` requires `2` fuel. This fuel requires no further fuel (2 divided by 3 and rounded down is `0`, which would call for a negative fuel), so the total fuel required is still just `2`.
• At first, a module of mass `1969` requires `654` fuel. Then, this fuel requires `216` more fuel (`654 / 3 - 2`). `216` then requires `70` more fuel, which requires `21` fuel, which requires `5` fuel, which requires no further fuel. So, the total fuel required for a module of mass `1969` is `654 + 216 + 70 + 21 + 5 = 966`.
• The fuel required by a module of mass `100756` and its fuel is: `33583 + 11192 + 3728 + 1240 + 411 + 135 + 43 + 12 + 2 = 50346`.

What is the sum of the fuel requirements for all of the modules on your spacecraft when also taking into account the mass of the added fuel? (Calculate the fuel requirements for each module separately, then add them all up at the end.)

Upon reading this, my first thought was:

The trick to writing recursive functions is to solve the “escape” case first — that is, the case where you stop the recursion and just return a value.

For this problem, the “escape” case is when the repeated fuel calculation gives a result of 0 or less:

Otherwise, take the result, and apply the fuel calculation to it again. That’s what gives us the recursive part. Here’s the resulting `if` statement:

And finally, we have to handle the initial calculation. The end result is the `fuel_required` function:

Now that we have the `fuel_required` function, we can apply it to every item in the `masses` array from part one:

This yields the updated fuel requirements for each module. The final step was to get their sum:

Entering the value of `updated_total_fuel` into the solution text field completed the day one challenge.

## One reply on “The Advent of Code is coming in a few days!”

[…] I wrote in the previous post, the Advent of Code is happening soon — it start on Tuesday, December 1st and runs all the way to […]