bjorng

bjorng

Erlang Core Team

Advent of Code 2024 - Day 1

Here is my solution for day 1 of Advent of Code:

defmodule Day01 do
  def part1(input) do
    all = parse(input)
    {first, second} = Enum.unzip(all)
    Enum.zip([Enum.sort(first), Enum.sort(second)])
    |> Enum.map(fn {a, b} ->
      abs(a - b)
    end)
    |> Enum.sum
  end

  def part2(input) do
    all = parse(input)
    {first, second} = Enum.unzip(all)
    frequencies = Enum.frequencies(second)
    first
    |> Enum.map(fn n ->
      n * Map.get(frequencies, n, 0)
    end)
    |> Enum.sum
  end

  defp parse(input) do
    input
    |> Enum.map(fn line ->
      {first, line} = Integer.parse(line)
      line = String.trim(line)
      {second, ""} = Integer.parse(line)
      {first, second}
    end)
  end
end

Most Liked

al2o3cr

al2o3cr

I liked this solution for part 1 because of the unzip / process / zip pattern:

File.stream!("example.txt")
|> Stream.map(&String.trim/1)
|> Stream.map(&String.split/1)
|> Stream.map(fn [a, b] -> {String.to_integer(a), String.to_integer(b)} end)
|> Enum.unzip()
|> then(fn {l, r} -> [Enum.sort(l), Enum.sort(r)] end)
|> Stream.zip()
|> Stream.map(fn {a, b} -> abs(b-a) end)
|> Enum.sum()
|> IO.inspect()

Part 2 wasn’t quite as symmetrical:

{left, right} =
  File.stream!("input.txt")
  |> Stream.map(&String.trim/1)
  |> Stream.map(&String.split/1)
  |> Stream.map(fn [a, b] -> {String.to_integer(a), String.to_integer(b)} end)
  |> Enum.unzip()

f_right = Enum.frequencies(right)

left
|> Stream.map(fn l -> {l, Map.get(f_right, l, 0)} end)
|> Stream.map(fn {l, n} -> l * n end)
|> Enum.sum()
|> IO.inspect()

Technically it would be faster to fuse successive Stream.maps into a single one with a more-complicated function, but writing in this style keeps each line focused on a specific transformation.

clayscode

clayscode

Signed up just to say thank you for this comment! Didn’t know about the then function. Subsequently have learned about the tap function as well thanks to this article: Useful Elixir Functions You May Not Know: tap() & then()

I guess it’s not that different from |> fn x -> x end.(), but it at least feels a bit nicer.

dimitarvp

dimitarvp

I got so severely humbled by @billylanchantin that I just copied his code with very slight changes like adding types and specs and doctests, and extracting functions for better understanding of what does what, plus have common AOC helpers in a separate module.

In my defense for stealing his code, I did stare at the code for 40 minutes and played with it in iex until I understood exactly how it’s working. And then I was finally like “gods, I would absolutely do it this way if I knew about this Elixir API!”.

But yeah, I had no idea about Enum.zip_with and Enum.zip_reduce. Lesson learned – check Elixir’s CHANGELOGs!

Here’s my final Day 1 version:

woojiahao

woojiahao

Pretty fun despite it’s simplicity, but the prompts are getting looong:

defmodule AOC.Y2024.Day1 do
  @moduledoc false

  use AOC.Solution

  @impl true
  def load_data() do
    Data.load_day(2024, 1)
    |> Enum.map(&String.split(&1, ~r/\s+/, trim: true))
    |> Enum.map(fn [a, b] -> {String.to_integer(a), String.to_integer(b)} end)
    |> Array.transpose()
  end

  @impl true
  def part_one([l, r]) do
    l
    |> Enum.sort()
    |> Enum.zip(Enum.sort(r))
    |> General.map_sum(fn {a, b} -> abs(a - b) end)
  end

  @impl true
  def part_two([l, r]) do
    Enum.frequencies(r)
    |> then(fn freq ->
      General.map_sum(l, fn a -> a * Map.get(freq, a, 0) end)
    end)
  end
end

Github: aoc/lib/aoc/y2024/day_1.ex at main · woojiahao/aoc · GitHub (made a whole bunch of utility modules and functions from past years, to reduce code duplication)

pehbehbeh

pehbehbeh

Here are my solutions using Livebook:

Where Next?

Popular in Challenges Top

lud
Gosh this one took me sooo much time. At first I was trying to iterate each digit independently on the input A number to make digits cha...
New
Aetherus
This topic is about Day 7 of the Advent of Code 2020 . Thanks to @egze, we have a private leaderboard: https://adventofcode.com/2020/le...
New
antoine-duchenet
Everything went smoothly today. Nothing to change to solve part 2 because I already used memoization for part 1 (it looked like an AoC e...
New
sneako
Note by the Moderators: This topic is to talk about the first day of the Advent of Code. For general discussion about the Advent of Code...
New
Aetherus
I tried to use combinatorial to solve today’s puzzles but failed (my brain burned out :exploding_head:). In the end I just used brute for...
New
shritesh
This was way too easy after the last few days. Simple map, filter and count.
New
New
bjorng
Note: This topic is to talk about Day 5 of the Advent of Code 2019. There is a private leaderboard for elixirforum members. You can join...
New
bjorng
Note: This topic is to talk about Day 23 of the Advent of Code. For general discussion about the Advent of Code 2018 and links to topics...
New
cblavier
Hey there :wave: No magic or algorithmic finesse today, I just finished the challenge and I my code is quite slow (1sec for part1, 3se...
New

Other popular topics Top

9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New

We're in Beta

About us Mission Statement