Getting Started With Advent of Code

NOTE: This is my second post discussing Advent of Code. Check out the first post to learn more about why I love AoC.

Advent of Code is only a day away! I can't wait to get started. If you're thinking about trying Advent of Code but you're not sure where to start, I hope I can share some tips.

First and foremost, make sure you've signed up at adventofcode.com. Each day, a new puzzle will become available at midnight. Now that you've signed up, let's talk about how to start writing some code to solve each puzzle.

It's often difficult to start on any programming project. The number of options and approaches can feel overwhelming. I definitely experience this sensation of overwhelm when starting a project. Over the years, I've learned strategies for overcoming some of the anxious thoughts that can creep in when just getting started with something. The strategy I come back to time after time is to start with the simplest approach that works.

This is the strategy that I recommend for jumping into Advent of Code. In this post, I'll demonstrate two simple templates that should make it fairly easy to get started solving Advent of Code problems.

There are other resources that suggest templates that will automatically download your input and submit your output. Or that will even show performance benchmarks for each of your solutions. These are great, but I think it's even more fun to start simple and introduce your own features as you get more comfortable using a basic setup.

If you want to check out a great example of a more advanced setup, Anthony Sottile posted a great video demonstrating his template for solving AoC quickly.

Python

I love solving the problems with python each year. For small puzzles like those in AoC, python gives you a lot of power with very little ceremony.

For a basic setup, I recommend using the fileinput module from the standard library. This library takes care of all of the boilerplate of loading input files and makes it easy to swap in a sample input if you want to debug your solution on a simpler example.

Usually, I start with something like this:

import fileinput

lines = [line.strip() for line in fileinput.input()]

If I've saved my solution to a file named sol.py and my input to a file named input.txt, then I can run my solution by running the command:

python3 -m sol input.txt

Let's see how it looks to solve day 1 part 1 from the 2021 edition of Advent of Code.

 import fileinput

-lines = [line.strip() for line in fileinput.input()]
+depths = [int(line.strip()) for line in fileinput.input()]
+
+
+result = 0
+for i in range(len(depths) - 1):
+  if depths[i] < depths[i + 1]:
+    result += 1
+print("Part one:", result)

As you can see, most of the adjustments that we've made are focused on just solving the specifics of the problem. First we parse an integer from each line, then we are able to walk our list to figure out how many times the depth increases.

JavaScript

JavaScript is a great language for getting started learning to code especially because the web is such a ubiquitous platform. There are several excellent JavaScript runtimes that you can use to solve AoC problems in JavaScript. I recommend node.js as it is the most popular server-side JavaScript platform.

Unfortunately, node does not provide quite as much convenience as python (and its enormous standard library). But once you get past the boilerplate setup, it's not so bad!

Let's take a look:

const fs = require("fs");

const input = fs.readFileSync("./input.txt").toString();
const lines = input.split("\n").map((s) => s.trim());

To run this, assuming that I've saved this to sol.js (and the input to input.txt) I can run the command:

node sol.js

Note that we've hardcoded the path of the input file, so you'll have to do a little bit more work to test out your solution on a sample input. It's possible to recreate our setup from the python section with a little bit of research on command line argument parsing (see the docs on process.argv for more details).

Now let's see what it looks like to solve 2021 day 1 part 1 in JavaScript:

 const fs = require("fs");

 const input = fs.readFileSync("./input.txt").toString();
-const lines = input.split("\n").map((s) => s.trim());
+const depths = input.split("\n").map((s) => parseInt(s.trim()));
+
+let result = 0;
+for (let i = 0; i < depths.length - 1; ++i) {
+  if (depths[i] < depths[i + 1]) {
+    ++result;
+  }
+}
+console.log("Part one:", result);

Not too bad!

Wrap Up

As you can see, it's possible to get started solving Advent of Code puzzles with just a little bit of setup. Once you've solved your first few puzzles, it can be fun to experiment with different ways to speed up your solutions or to automatically handle fetching your input or submitting your output. But it's fine to start simple! Hopefully you'll join me tomorrow night (and the rest of the month) in solving some festive puzzles!

Good luck!

Why I love Advent of Code

NOTE: This will be the first post in a short series of maybe 2 or 3 posts discussing Advent of Code.

Advent of Code is one of my favorite "events" each year. In case you haven't heard of it, Advent of Code (AoC) is an Advent calendar that consists of 25 programming puzzles of varying levels of difficulty. Each puzzle consists of two parts: the first part is released at 12 AM EST each day and the second part of each puzzle is only unlocked upon completing the first part.

Here are a few reasons why I think AoC is great:

  • Community
  • Progressive difficulty
  • Theming

Community

More than almost any other programming competition, AoC fosters a wonderful supportive community.

There is a fantastic subreddit: old.reddit.com/r/adventofcode/ devoted to AoC with a daily thread for participants to share their solutions. And there are often fun posts with visualizations or other AoC themed content. There are great discussions of why different approaches might work better than others or helping out with tricky bits of the puzzles.

From an official perspective, there is a very competitive main leaderboard available for folks to compete for the fastest solutions each day. But you can also create and join private leaderboards to have a friendly competition among friends and/or colleagues. Many of the top scorers on the main leaderboard have YouTube channels and/or public repositories to display their solutions.

Here are a couple of my favorite YouTube channels for watching rapid solutions:

  • Jonathan Paulson: Consistently close to the top of the leaderboards, I've learned a good bit about rapidly coding and debugging in python and Jonathan usually includes a walkthrough of the puzzle and solution at the end of each video.
  • Neal Wu: Neal produces solutions in C++ incredibly quickly with a satisfyingly clicky keyboard. Neal also has videos of himself competing in (and often winning) several other programming competitions.

There are also many channels that have videos walking through solutions from a pedagogical perspective:

  • Anthony Sottile: Great educational python videos and usually creates a playlist with AoC solutions each year.
  • Liz Fong-Jones: SRE and observability guru who solves AoC on stream each year and posts the recordings to YouTube. Solved 2021 in Go.

And there are many channels with solutions in... unconventional styles:

  • Mitchell Hashimoto: The founder of HashiCorp produced solutions to days 1-7 of AoC 2021 in PostgreSQL.
  • Mark Gritter: An engineer at Akita Software wrote solutions to all of 2021 in F*!

There are so many fun variations on AoC solutions to find and explore.

Progressive difficulty

AoC usually starts out fairly simple and works up to a pretty good difficulty, usually reaching close to the peak around day 15. This makes AoC an ideal candidate for learning! Whether you're trying out a new programming language or a new library or style, AoC is a fantastic resource to push yourself to get familiar with your tools, new and old.

Since the puzzle inputs are provided as plain text, the early puzzles emphasize basic string processing techniques in your chosen language. Even as a professional programmer, it's really helpful to get more comfortable with the standard library from time to time. I typically try to solve each puzzle as quickly as possible in python and then jump to a programming language that I want to know better. Usually, I spend the early puzzles getting familiarized with the standard library in the second language before the difficult really ramps up. Once the puzzles get more challenging, it's a good opportunity to see how problem solving approaches differ across different programming languages.

Since the early puzzles are usually not too difficult, AoC is great for getting folks of all different skill levels to dip their toe in and then start learning new techniques for solving puzzles using their toolset.

Theming

A lot of other programming competitions have fairly dry and minimal presentations for their puzzles. Eric Wastl (the creater of AoC) puts a ton of care into the preparation of the prompts for each puzzle, often relating the puzzles back to a common holiday-related theme. This is just plain fun. Eric has appeared in many videos providing a behind-the-scenes look at AoC and its history.

At the end of the day, these details help AoC bring a ton of joy to my holiday season.

Wrapping up

I think Advent of Code is one of the coolest programming-related events of the year. It's a chance to learn, struggle and grow as part of a larger coding community. Give it a shot in a couple of weeks! In the meantime, you can explore the puzzles from previous years to prepare.

Stay tuned for my next post on putting together an AoC template in a few different languages.