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
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
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
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
This one has been quite the ride. Struggled at first to find a good data format to suite the problem. I really like how that turned out b...
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
Note: This topic is to talk about Day 10 of the Advent of Code 2019 .
There is a private leaderboard for elixirforum members. You can jo...
New
Phew, this one took a while to get right. My naive attempts was way to slow so I reached for Dijkstras shortest path algorithm.. and that...
New
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
This was way too easy after the last few days. Simple map, filter and count.
https://github.com/shritesh/advent/blob/main/2023/06.livemd
New
This topic is about Day 4 of the Advent of Code 2020 .
Thanks to @egze, we have a private leaderboard:
https://adventofcode.com/2020/le...
New
Other popular topics
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch.
This project took far...
New
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
Hello all!
I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set?
Thanks.
New
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
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
Hi guys, i’m new in the Elixir world, and i have to say, that i love it!
i’m having some problem to understand anonymous functions with ...
New
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
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
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
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








