bjorng
Erlang Core Team
Advent of Code 2025 - Day 5
Easy puzzles two days in a row. I suspect tomorrow’s puzzle will not be that easy…
defmodule Day05 do
def part1(input) do
{ranges, ingredients} = parse(input)
Enum.count(ingredients, &in_any_range?(&1, ranges))
end
defp in_any_range?(ingredient, ranges) do
Enum.any?(ranges, &(ingredient in &1))
end
def part2(input) do
{ranges, _ingredients} = parse(input)
ranges = ranges
|> Enum.sort
|> combine_ranges
Enum.reduce(ranges, 0, &(Range.size(&1) + &2))
end
defp combine_ranges([r]), do: [r]
defp combine_ranges([r1, r2 | rest]) do
case Range.disjoint?(r1, r2) do
true ->
[r1 | combine_ranges([r2 | rest])]
false ->
r = min(r1.first, r2.first) .. max(r1.last, r2.last)
combine_ranges([r | rest])
end
end
defp parse([ranges, ingredients]) do
ranges = Enum.map(ranges, fn range ->
[first, last] = String.split(range, "-")
String.to_integer(first) .. String.to_integer(last)
end)
ingredients = Enum.map(ingredients, &String.to_integer(&1))
{ranges, ingredients}
end
end
Most Liked
hauleth
That is why I created RangeSet:
Parse
[fresh, ingridients] = String.split(puzzle_input, "\n\n")
fresh =
fresh
|> String.split()
|> Enum.map(fn range ->
[a, b] = range |> String.split("-") |> Enum.map(&String.to_integer/1)
a..b//1
end)
|> RangeSet.new()
ingridients =
ingridients
|> String.split()
|> Enum.map(&String.to_integer/1)
Part 1
Enum.count(ingridients, & &1 in fresh)
Part 2
Enum.count(fresh)
7
mudasobwa
Creator of Cure
For the first time I needed a helper private function with multiple heads to handle a recursion properly.
defmodule Day5 do
@input "day5_1.input" |> File.read!() |> String.split("\n\n", trim: true)
def calc([ranges, ids] \\ @input) do
ranges =
ranges
|> String.split(["\s", "\n"], trim: true)
|> Enum.map(&String.split(&1, "-", trim: true))
|> Enum.map(fn [b, e] -> String.to_integer(b)..String.to_integer(e)//1 end)
ids
|> String.split(["\s", "\n"], trim: true)
|> Enum.reduce({0, []}, fn id, {count, ids} ->
id = String.to_integer(id)
Enum.reduce_while(ranges, {count, ids}, fn range, {count, ids} ->
if id in range, do: {:halt, {count + 1, [id | ids]}}, else: {:cont, {count, ids}}
end)
end)
end
def in_ranges([ranges, _ids] \\ @input) do
ranges
|> String.split(["\s", "\n"], trim: true)
|> Enum.map(&String.split(&1, "-", trim: true))
|> Enum.map(fn range -> Enum.map(range, &String.to_integer/1) end)
|> Enum.sort()
|> merge([])
|> Enum.sum_by(fn [f, l] -> l - f + 1 end)
end
defp merge([], acc), do: Enum.reverse(acc)
defp merge([range | rest], []), do: merge(rest, [range])
defp merge([[f2, l2] | rest], [[f1, l1] | acc]) do
if f2 <= l1 + 1 do
merged = [f1, max(l1, l2)]
merge(rest, [merged | acc])
else
merge(rest, [[f2, l2], [f1, l1] | acc])
end
end
end
4
vkryukov
Yep, today was an easy one; parsing takes almost more lines than the rest of the code :).
defmodule Y2025.Day05 do
def fresh?(_id, []), do: false
def fresh?(id, [{a, b} | rest]) do
cond do
id < a -> false
a <= id && id <= b -> true
true -> fresh?(id, rest)
end
end
def parse(s) do
[ranges, ids] = String.split(s, "\n\n")
ranges =
ranges
|> String.split("\n")
|> Enum.map(fn line ->
[a, b] = String.split(line, "-")
{String.to_integer(a), String.to_integer(b)}
end)
|> Enum.sort() # <- important for fresh? and do_part2 to work!
ids = ids |> String.split("\n") |> Enum.map(&String.to_integer/1)
{ranges, ids}
end
def part1(s) do
{ranges, ids} = parse(s)
ids
|> Enum.filter(fn id -> fresh?(id, ranges) end)
|> length()
end
def part2(s) do
{ranges, _} = parse(s)
do_part2(ranges, 0)
end
def do_part2([], n), do: n
def do_part2([{a, b}], n), do: n + b - a + 1
def do_part2([{a, b}, {c, d} | rest], n) do
cond do
b < c -> do_part2([{c, d} | rest], n + b - a + 1)
b >= d -> do_part2([{a, b} | rest], n)
# b >= c & b < d
true -> do_part2([{a, d} | rest], n)
end
end
end
3
Popular in Challenges
Ok, that was a rough one today.
I haven’t found a way to improve the algorithm further. Part 1 runs in .5 seconds, Part 2 in ~ 5 minutes...
New
Not the prettiest but it works
https://github.com/rugyoga/aoc2023/blob/main/lib/2024/9.ex
New
Reasonably pleased with my solution. The bitstring packet problems are so well suited to Erlang/Elixir it’s almost not fair.
defmodule D...
New
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
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
Note by the Moderators: This topic is to talk about Day 6 of the Advent of Code.
For general discussion about the Advent of Code 2018 an...
New
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
Hi, there :wave:
Today, I felt it was way more challenging! I went through part2 thanks to Agent based memoization (without memoization ...
New
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
This topic is about Day 16 of the Advent of Code 2020 .
Thanks to @egze, we have a private leaderboard:
https://adventofcode.com/2020/l...
New
Other popular topics
I have an umbrella app.
Some of the apps inside depend on other apps in the umbrella, unsurprisingly.
I’m writing a test for one of the...
New
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors:
[WARN] - (starship::utils): Executing command ...
New
Hi folks,
Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
New
I tried installing
elixir 1.11.2
erlang 23.3.4
via asdf in my zsh shell. Enabled the versions locally and globally.
When I list them ...
New
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
I had some trouble figuring out how to make many-to-many associations work. Once I got it working, I wrote a blog post. Because I’m a nov...
New
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








