If you know me, you know that I’m a huge fan of programming challenges and code katas. Sometimes I think I missed my calling as a competitive programmer.

This past month I was able to satisfy my cravings for programming challenges with Eric Wastl’s Advent of Code.

Solving a programming challenge every day for nearly a month taught me interesting lessons about myself and my current programming language of choice: Elixir.

Here’s a quick rundown.

  • You’ll have good days. - There will be days where your mind is running on all cylinders. Solutions to problems will appear fully formed in your mind’s eye, and completing challenges is simply a matter of dictating your envisioned solution.

  • You’ll have bad days. - There will be other days where your mind feels like a tangle of rusty nails stuck together in a bucket of dried cement. Solutions will come slowly, if they come at all.

  • Most days will land somewhere in-between. - It’s important to try to avoid letting your perceived state of mind influence your decisions and determination. When I felt like I was having trouble, falling back to first principles always seemed to help devise a path forward.

  • Elixir’s Stream library is awesome. - Sasa Juric’s solutions to the first few days of Advent of Code inspired me to look into Elixir’s Stream module. I was so impressed with the module that I wrote an article on generating sequences with streams, and I went on to solve a good number of advent challenges with Stream-based generators.

  • Stick to the basics. - I found that my first instinct when sketching out a solution to a problem was to reach for functions shipped in standard modules like Enum, List, and Map. However, studying other people’s solutions made me realize that sticking to the basics of recursion and pattern matching can lead to more elegant, readable, and performant solutions.

  • Erlang ships with everything and the kitchen sink. - A few of this year’s challenges led me to standard modules shipped with Erlang and accessible from Elixir. Modules like :digraph, :digraph_utils, :gb_trees, and :binary are incredibly useful and overlook utilities.

  • You don’t want to split on empty strings. You want a list of graphemes. - Use String.graphemes/1 instead of String.codepoints/1 or String.split(&1, "") to split a string into its component characters. Read all about codepoints and grapheme clusters for more information.

  • Elixir’s “extended” regex modifier helps explain away the black magic. - Regexes are often cesspools of black magic. It often takes just as long, if not longer, to understand a written regex than to write it from scratch. Thankfully, Elixir’s “extended” modifier lets you explain away some of the black magic in your regexes by splitting them across multiple lines and interleaving comments.

  • Studying other people’s solutions can teach powerful lessons. - Nearly every language-specific tip or technique I learned during this year’s Advent of Code challenge came from studying other people’s solutions after I implemented my own. Reading other people’s code is, hands down, the most powerful tool for improving your own code.

I had a lot of fun with this year’s Advent of Code challenges. I learned quite a bit about Elixir and about myself. I even made some good friends in the #adventofcode channel of the Elixir Slack group.

I’ll definitely be doing this again next year.

If you didn’t do this year’s Advent of Code, it’s not too late! Go check out the problems, and if you’re curious, check out my solutions on Github.