/adventofcode-2021-elixir

Elixir solutions for Advent of Code 2021

Primary LanguageElixir

Advent of Code 2021, solved with Elixir

Advent of Code is back! Last year (and the year before that), I took a stab at it using Elixir, but only had time to solve two problems. This year I’m trying again.

I’ve used Elixir only sparingly, so hopefully a month of consistent floundering will expand my mental paradigm of what “programming” actually looks like (as Ruby, Clojure, functional programming, etc. have). So, onward to the code:

Instructions

Assuming that Elixir is installed:

  1. Solving the day’s problem:

    elixir day-01/solution.exs

  2. Running tests:

    elixir -r day-01/solution.exs day-01/tests.exs

Lessons Learned

Day 1:

  1. The Elixir docs are great and comprehensive and the examples are often relevant to actual problems, compared to many languages.

  2. IO.inspect/2 works within pipelines, which is very convenient for debugging. I’ll be using this trick often:

    [1, 2, 3]
    |> IO.inspect(label: "before")
    |> Enum.map(&(&1 * 2))
    |> IO.inspect(label: "after")
    |> Enum.sum
    
    # before: [1, 2, 3]
    # after: [2, 4, 6]
    # 12
  3. Maybe/probably I’m overusing pipelines, but their tidy syntax works for my brain, and it’s striking how effectively they reduce the need to solve one of the two hard things in Computer Science. 🔥

Day 2:

  1. Maps have a nice shorthand syntax for updating existing values:

    map = %{one: 1, two: 2, three: 3}
    %{map | one: "one", three: "three"}
    
    # %{one: "one", two: 2, three: "three"}
  2. Nested modules aren’t a thing, really. I mean, kind of. They do exist, and share imports and aliases, but not functions.

Day 3:

I tried really hard to use bitwise operators on Part 1, but it turns out I don't understand how Elixir handles binary strings. And that strategy wouldn’t have worked for Part 2 anyway, so I wasted a bunch of time on an unnecessary premature optimization.

Day 5:

Destructuring, wow. It's amazing that this:

[startpoint, endpoint] = line
x = Enum.at(endpoint, 0) - Enum.at(startpoint, 0)
y = Enum.at(endpoint, 1) - Enum.at(startpoint, 1)
[[x1, y1], [x2, y2]] = line