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
Note: This topic is to talk about Day 12 of the Advent of Code.
For general discussion about the Advent of Code 2018 and links to topics...
New
This topic is about Day 8 of the Advent of Code 2020 .
Thanks to @egze, we have a private leaderboard:
https://adventofcode.com/2020/le...
New
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
My solution finishes both parts in 5 seconds on my computer. That time should be possible to reduce by optimizing my rather naive tilt/2 ...
New
Note: This topic is to talk about Day 16 of the Advent of Code 2019.
There is a private leaderboard for elixirforum members. You can joi...
New
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
Hello all, hopefully I post this before someone else does and I don’t dupe.
IMO Day 4 was much easier than Day 3 (yay, I can sleep befor...
New
Don’t know why the regex ~r/[\W && [^\.]]/x does not work in Elixir. It works pretty well in Ruby.
Anyway, here is my solution: ...
New
Fairly straightforward Dijkstra’s algorithm
import AOC
aoc 2023, 17 do
def compute(input, candidates) do
{{max_row, max_col}, ite...
New
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
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
Phoenix 1.4.0 released
Phoenix 1.4 is out! This release ships with exciting new features, most notably
with HTTP2 support, improved deve...
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
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
I have VueJS GUIs with the project generated using Webpack.
I have Elixir modules that will need to be used by the VueJS GUIs.
I forese...
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
Hi everyone,
I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
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
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








