Advent of Code 2019 - Day 3

Note: This topic is to talk about Day 3 of the Advent of Code 2019 .

There is a private leaderboard for elixirforum members. You can join it by following this link and entering the following code:


1 Like

Here is my solution.


Today was a bit finicky. Here’s my take.


That was weird to do functionally.


Todays solution is a bit earlier as usual for me, as I currently can’t do office work as we have an internet outage. Doing this per mobile connection sharing right now.

Solution is at github, as usual.

Implementation is pretty straight forward after one has realised that we are basically just dealing with 2 sets and we want to know where they intersect :wink:

Though code clean up has to wait, as I have to attend to a meeting in a couple of minutes, which we will hold as scheduled despite the internet problem.


I have a bug I can’t figure out, please help ^^

It works fine on simple tests, but when running on full puzzle input, it gives me a wrong shortest distance (=1). It also gives me the good answer but only in second rank

Ok finally found it : I had a bug in inc_pos_x / inc_pos_y when dealing with negative distances

Here is my final solution by the way

1 Like

Very elegant!

1 Like

at the moment so try to learn Elixir. So I will solve the advent of code for better understanding of Elixir.
Currently I only solved Day 1 and 2. I hope I find some time this week to solve the next days :slight_smile:
Here is a link to the repo: repo.

I’d appreciate your feedback.

1 Like

Could you walk us through your implementations in the appropriate days thread?

I only glanced, and they look as if they only provide a single solution each, rather than tackling both problems of the given day.

1 Like

Sure, I overlooked that this thread is only for the third day.
And then I’ll adjust the solutions again so that both solutions are there and not just the second solution.

1 Like

Here’s my erlang take on day 3:


Mine was a bit messier today, but I’ll leave it as it is.

I spent a bit of time wondering how I was going to approach this (DFS?). Then I realized I can simply expand the coords to find overlaps. That’s a bit brute Force, but it still cleared it in under 100ms

1 Like

My solution today is very ugly. I wrote a lot more code than needed because I kept track of “steps” or length along with each point, which, upon reading other solutions, it’s obvious that I didn’t need. Everywhere I used ...) is where I couldn’t come up with something better.

One thing I felt I missed was Map.merge that takes a list of maps, instead of two maps. Having to write Enum.reduce(ls_of_maps, %{}, fn x, acc -> Map.merge(acc, x) end) seemed like extra work.

1 Like

I ended up doing the same and tracking all points as well. In retrospect (and once it’s no longer 15 minutes after I got up) it’s obvious you don’t need it that way, but it’s rather straightforward to count steps after the fact for part 2 anyway if you went with that approach for part 1.

1 Like

I’m having a great time defining a sort of runner/pattern for my advent of code… I think this is my second or third year trying in elixir.

This year’s (current) model is using @callback to define a sort of API that all Advent problems have to solve:

defmodule Advent do
  @moduledoc """
  This is intended to be an importable module that defines some runners and
  conventions for advent of code problems.

  Each "day" should contain the following methods...

  - `setup/0` should setup a input object.
  - `p1/1` and `p2/2` should take the input and solve the puzzle, returning the

  I want to define a test runner such that if you run mix <day number> it runs
  `setup/0` once and runs `p1/1` and/or `p2/1` when appropriate.

  @callback setup() :: {:ok, term}
  @callback p1(Map.t) :: {:ok, term}
  @callback p2(Map.t) :: {:ok, term}

If you look at the whole file here, it also defines some timing functions as a mix task.

This pattern really became really fun for today’s puzzle. As I started into part 2, more of p1 moved up into setup/0 so that p1/1 and p2/1 are just the specific solutions to their part.

For instance:

  def p1(%{intersections: intersections}) do
    |> Enum.min_by(fn({x, y}) -> abs(x) + abs(y) end)
    |> (fn({x, y}) -> abs(x) + abs(y) end).()


  def p2(%{wires: {wire1, wire2}, intersections: intersections}) do
    |> ->
        Enum.find_index(Enum.reverse(wire1), & coord == &1) +
        Enum.find_index(Enum.reverse(wire2), & coord == &1),
    |>{combined_distance, _}) -> combined_distance end)
    |> Enum.min

full day 3 solution here

Pretty hacky but it works and is reasonably speedy:

Here is my solution:

My solution:

This time my stream was saved :slight_smile:

Code is here.