hauleth

hauleth

Advent of Code 2025 - Day 11

Graph traversals


Parse

graph =
  puzzle_input
  |> String.split("\n", trim: true)
  |> Map.new(fn <<from::binary-3>> <> ": " <> rest ->
    {from, String.split(rest)}
  end)

Implementation

defmodule Servers do
  def paths(graph, from, to), do: paths(graph, from, to, [from])

  defp paths(_graph, to, to, acc), do: [Enum.reverse(acc)]

  defp paths(graph, from, to, acc) do
    if next = graph[from] do
      Stream.flat_map(next, &paths(graph, &1, to, [&1 | acc]))
    else
      []
    end
  end

  def paths_through(graph, from, to, required),
    do: path_through(graph, from, to, MapSet.new(required), %{})

  defp path_through(_graph, to, to, required, memo),
    do: {if(Enum.empty?(required), do: 1, else: 0), memo}

  defp path_through(graph, from, to, required, memo) do
    state = MapSet.delete(required, from)

    with :error <- Map.fetch(memo, {from, state}),
         {:ok, next} <- Map.fetch(graph, from) do
      {sum, memo} =
      Enum.reduce(next, {0, memo}, fn n, {sum, acc} ->
        {c, next_acc} = path_through(graph, n, to, state, acc)

        {c + sum, next_acc}
      end)

      {sum, Map.put(memo, {from, state}, sum)}
    else
      :error -> {0, memo}
      {:ok, val} -> {val, memo}
    end
  end
end

Part 1

Servers.paths(graph, "you", "out") |> Enum.count()

Part 2

Servers.paths_through(graph, "svr", "out", ["dac", "fft"])
|> elem(0)

First Post!

lud

lud

A similar solution but I divided the work in multiple steps:

count(svr -> fft) * count(fft -> dac) * count(dac -> out)

defmodule AdventOfCode.Solutions.Y25.Day11 do
  alias AoC.Input

  def parse(input, _part) do
    input
    |> Input.stream!(trim: true)
    |> Map.new(&parse_line/1)
  end

  defp parse_line(line) do
    <<inp::binary-size(3), ": ", rest::binary>> = line
    {inp, String.split(rest)}
  end

  def part_one(full_io) do
    count_paths(full_io, "you", "out")
  end

  defp count_paths(full_io, start, finish) do
    counts = count_paths_loop(full_io, start, finish, Map.put(%{"out" => 0}, finish, 1))
    Map.fetch!(counts, start)
  end

  defp count_paths_loop(full_io, current, finish, acc) do
    exits = Map.fetch!(full_io, current)

    acc =
      Enum.reduce(exits, acc, fn exit_, acc ->
        if Map.has_key?(acc, exit_) do
          acc
        else
          count_paths_loop(full_io, exit_, finish, acc)
        end
      end)

    value = Enum.sum_by(exits, &Map.fetch!(acc, &1))

    Map.put(acc, current, value)
  end

  def part_two(full_io) do
    {step1, step2} =
      if count_paths(full_io, "fft", "dac") > 0 do
        {"fft", "dac"}
      else
        true = count_paths(full_io, "dac", "fft") > 0
        {"dac", "fft"}
      end

    count_paths(full_io, "svr", step1) *
      count_paths(full_io, step1, step2) *
      count_paths(full_io, step2, "out")
  end
end

Edit: simplified the parse, taking inspiration from hauleth’s :smiley:

Where Next?

Popular in Challenges Top

Aetherus
This topic is about Day 3 of the Advent of Code 2020 . Thanks to @egze, we have a private leaderboard: https://adventofcode.com/2020/le...
New
bjorng
This topic is about Day 17 of the Advent of Code 2020 . Thanks to @egze, we have a private leaderboard: https://adventofcode.com/2020/l...
New
sasajuric
Note by the Moderators: This topic is to talk about Day 5 of the Advent of Code. For general discussion about the Advent of Code 2018 an...
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
woolfred
It is that time of the year again: Advent of Code 2022 :christmas_tree: Day 1 Leaderboard:
New
jkwchui
Monkeys fitted squarely as GenServers in my head. My initial problem was using cast instead of call; I imagine impolite monkeys slinging...
New
coen.bakker
Since I started using Elixir, I have benefited greatly from being able to study various open-source projects. The codebase of LiveBook, i...
New
bjorng
Here is my solution for day 1 of Advent of Code: defmodule Day01 do def part1(input) do all = parse(input) {first, second} = E...
New
bjorng
Note: This topic is to talk about Day 13 of the Advent of Code 2019. There is a private leaderboard for elixirforum members. You can joi...
New
christhekeele
Thought I’d kick today’s thread off! Parsing Enum rocks, so most of my code was actually in parsing input. ▶ Preprocessing input Part 1...
New

Other popular topics Top

Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
Nvim
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help. Where are they similar? Where do they differ the m...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 53690 245
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" =&gt; #BSON.ObjectId&lt;58eb1a7a9ad169198c3dXXXX&gt;, "email" =&gt; ...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New

We're in Beta

About us Mission Statement