Aetherus

Aetherus

Advent of Code 2024 - Day 5

Today’s problem is really tense. I don’t think I can do it without libgraph.

Most Liked

ruslandoga

ruslandoga

Brute Enum.sort_by with String.contains?
def solve(input) do
  [rules, pages] = String.split(input, "\n\n")

  pages =
    pages
    |> String.split("\n", trim: true)
    |> Enum.map(fn line ->
      line |> String.split(",") |> Enum.map(&String.to_integer/1)
    end)

  Enum.reduce(pages, {0, 0}, fn page, {p1, p2} ->
    sorted =
      Enum.sort_by(page, &Function.identity/1, fn l, r ->
        String.contains?(rules, "#{l}|#{r}")
      end)

    mid = Enum.at(sorted, div(length(sorted), 2))

    if page == sorted do
      {p1 + mid, p2}
    else
      {p1, p2 + mid}
    end
  end)
end

Full: aoc2024/lib/day05.ex at master · ruslandoga/aoc2024 · GitHub

cblavier

cblavier

Easy part 1, I had to think more for part 2. I thought my approach would take an infinite time, but it didn’t (about 40ms)

I implemented a bubble sort like approach:

  • traverse the list of numbers
  • every time we find an invalid number (compared to all previous ones), swap them
  • then recursive call to traverse and fix the new swapped list.

Part 1

defmodule Advent.Y2024.Day05.Part1 do
  def run(puzzle) do
    {rules, updates} = parse(puzzle)

    updates
    |> Enum.filter(&valid?(&1, rules))
    |> Enum.map(&Enum.at(&1, &1 |> length |> div(2)))
    |> Enum.sum()
  end

  def parse(puzzle) do
    [rules, updates] = String.split(puzzle, "\n\n")

    rules =
      for rule <- String.split(rules, "\n"), reduce: MapSet.new() do
        acc ->
          [p1, p2] = String.split(rule, "|")
          MapSet.put(acc, {String.to_integer(p1), String.to_integer(p2)})
      end

    updates =
      for pages <- String.split(updates, "\n") do
        for page <- String.split(pages, ","),
            page = String.to_integer(page),
            do: page
      end

    {rules, updates}
  end

  def valid?(update, rules) do
    update
    |> Enum.reduce({[], true}, fn
      _page, {prev, false} ->
        {prev, false}

      page, {prev, _valid?} ->
        valid? = not Enum.any?(prev, &MapSet.member?(rules, {page, &1}))
        {[page | prev], valid?}
    end)
    |> elem(1)
  end
end

Part 2

defmodule Advent.Y2024.Day05.Part2 do
  alias Advent.Y2024.Day05.Part1

  def run(puzzle) do
    {rules, updates} = Part1.parse(puzzle)

    updates
    |> Enum.reject(&Part1.valid?(&1, rules))
    |> Enum.map(&for {p, i} <- Enum.with_index(&1), into: %{}, do: {i, p})
    |> Enum.map(&fix_update(&1, rules))
    |> Enum.map(&Map.get(&1, &1 |> Enum.count() |> div(2)))
    |> Enum.sum()
  end

  def fix_update(update, rules) do
    for i <- 1..(Enum.count(update) - 1), j <- 0..(i - 1), reduce: {nil, true} do
      {indexes, false} ->
        {indexes, false}

      {nil, true} ->
        {first, second} = {Map.get(update, j), Map.get(update, i)}

        if MapSet.member?(rules, {second, first}) do
          {{i, j}, false}
        else
          {nil, true}
        end
    end
    |> then(fn
      {nil, true} -> update
      {{i, j}, false} -> update |> swap(i, j) |> fix_update(rules)
    end)
  end

  defp swap(update, i, j) do
    update |> Map.put(i, Map.get(update, j)) |> Map.put(j, Map.get(update, i))
  end
end

Where Next?

Popular in Challenges Top

adamu
I said I was on a break, but I took a sneak peak and it looked fun so… Part 1 completes in half a millisecond with a single pass of the ...
New
igorb
So… that’s it? Everyone is stuck on part 2? :slight_smile: I looked at Reddit hints and thought I probably wouldn’t have come up with the...
New
bjorng
Here is my solution for day 2 of Advent of Code: https://github.com/bjorng/advent-of-code/blob/main/2024/day02/lib/day02.ex
New
bjorng
This topic is about Day 5 of the Advent of Code 2021. We have a private leaderboard (shared with users of Erlang Forums ): https://adve...
New
Aetherus
This topic is about Day 15 of the Advent of Code 2020 . Thanks to @egze, we have a private leaderboard: https://adventofcode.com/2020/l...
New
code-shoily
Here’s my day 3 code https://github.com/code-shoily/advent_of_code/blob/master/lib/2024/day_03.ex This was quite easy. I was afraid Par...
New
bjorng
Note: This topic is to talk about Day 25 of the Advent of Code 2019. There is a private leaderboard for elixirforum members. You can joi...
New
bjorng
Note: This topic is to talk about Day 6 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 9 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

Other popular topics Top

lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 47930 226
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
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" =&gt; #BSON.ObjectId&lt;58eb1a7a9ad169198c3dXXXX&gt;, "email" =&gt; ...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

We're in Beta

About us Mission Statement