lud

lud

Advent of Code 2025 - Day 1

Hello everyone!

This year is going to be shorter, but the difficulty will grow faster. Today I already feel that this is not standard “Day 1” difficulty.

Or I am really overcomplicating things. Didn’t sleep well :smiley:

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

  def parse(input, :part_one) do
    input
    |> Input.stream!(trim: true)
    |> Enum.map(fn
      "R" <> n -> {:right, String.to_integer(n)}
      "L" <> n -> {:left, String.to_integer(n)}
    end)
  end

  def parse(input, :part_two) do
    input
    |> Input.stream!(trim: true)
    |> Enum.flat_map(fn
      "R" <> n -> expand_rotation(:right, String.to_integer(n))
      "L" <> n -> expand_rotation(:left, String.to_integer(n))
    end)
  end

  defp expand_rotation(direction, amount) when amount <= 100 do
    [{direction, amount}]
  end

  defp expand_rotation(direction, amount) when amount > 100 do
    [{direction, 100} | expand_rotation(direction, amount - 100)]
  end

  def part_one(problem) do
    problem
    |> Stream.scan(50, fn
      {:left, n}, acc -> Integer.mod(acc - n, 100)
      {:right, n}, acc -> Integer.mod(acc + n, 100)
    end)
    |> Enum.count(&(&1 == 0))
  end

  def part_two(problem) do
    problem
    |> Stream.transform(50, fn
      {:left, n}, acc ->
        new_acc = Integer.mod(acc - n, 100)
        {[{:left, acc, new_acc}], new_acc}

      {:right, n}, acc ->
        new_acc = Integer.mod(acc + n, 100)
        {[{:right, acc, new_acc}], new_acc}
    end)
    |> Enum.count(fn
      {_, _, 0} -> true
      {_, 0, _} -> false
      {:right, a, b} when a > b -> true
      {:left, a, b} when a < b -> true
      {_, same, same} -> true
      _ -> false
    end)
  end
end

Most Liked

billylanchantin

billylanchantin

Boilerplate

def file_to_lines(file), do: file |> File.read!() |> String.trim() |> String.split("\n")
def file_to_lines(file, fun), do: file |> file_to_lines() |> Enum.map(fun)

Part 1

def part1(file), do: file |> file_to_lines(&parse/1) |> count0()
def parse(l), do: l |> String.replace("R", "") |> String.replace("L", "-") |> Integer.parse() |> elem(0)
def count0(i), do: i |> Enum.scan(50, &Integer.mod(&1 + &2, 100)) |> Enum.count(&(&1 == 0))

Enum.scan/3 works really well here.

Part 2

def part2(file), do: file |> file_to_lines(&parse/1) |> Stream.flat_map(&flatten/1) |> count0()
def flatten(x), do: if(x < 0, do: List.duplicate(-1, abs(x)), else: List.duplicate(1, x))

It’s tempting to do math, but reusing prior work is simpler if less performant.

tnlogy

tnlogy

Hi! Nice to see some solutions to compare with since this is my first time using Elixir. I like it so far :).

This is my solution for day1, I tried to simplify part 2 by replacing the instructions with just +1 and -1. Maybe some of my code is a bit strange since I’m new to Elixir.

defmodule Advent2025Test do
  use ExUnit.Case
  doctest Advent2025

  def day1_data() do
    "day1.txt"
    |> File.stream!()
    |> Stream.map(fn line -> String.split_at(line, 1) end)
    |> Stream.map(fn {dir, num} -> {dir, String.to_integer(String.trim(num))} end)
  end

  def day1_count(data) do
    data
    |> Enum.reduce({50, 0}, fn {dir, num}, {val, res} ->
      Integer.mod(
        val +
          case dir do
            "L" -> -num
            "R" -> num
          end,
        100
      )
      |> then(fn new_val ->
        {new_val, if(new_val == 0, do: res + 1, else: res)}
      end)
    end)
  end

  def day1_make_ticks(data) do
    data
    |> Stream.flat_map(fn {dir, num} ->
      Stream.map(1..num, fn _ -> {dir, 1} end)
    end)
  end

  test "day1_p1" do
    {_, zeroes} = day1_data() |> day1_count()
    IO.puts("answer #{zeroes}")
    assert zeroes == 1048
  end

  test "day1_p2" do
    # Same as part1, but make a list of just {"L", 1} and {"R", 1}
    {_, zeroes} = day1_data() |> day1_make_ticks() |> day1_count()
    IO.puts("answer: #{zeroes}")
    assert zeroes == 6498
  end
end

lkuty

lkuty

I wanted to play a little bit with nimble_parsec. I will try to use it for every parsing job. Usually I use regexes but 1) time to change, 2) and get a more powerful parsing technique.

#!/usr/bin/env elixir

# Advent of Code 2025. Day 1

Mix.install([
  {:nimble_parsec, "~> 1.4.2"},
])

defmodule M do
  import NimbleParsec

  rotation =
    choice([string("L"), string("R")])
    |> integer(min: 1)

  defparsec :rotation, rotation
end

# Part 1
File.stream!("../day01.txt")
|> Stream.map(fn line -> {:ok, [dir, qty], "\n", %{}, _, _} = M.rotation(line) ; {dir, qty} end)
|> Enum.reduce({50, 0}, fn {dir, qty}, {pos, zeroes} ->
  pos =  Integer.mod(pos + (if dir == "R", do: 1, else: -1) * qty, 100)
  {pos, (if pos == 0, do: zeroes+1, else: zeroes)}
end)
|> tap(fn {_pos, zeroes} -> IO.puts("Day 1. Part 1. Number of zeroes: #{zeroes}") end)

# Part 2
File.stream!("../day01.txt")
|> Stream.map(fn line -> {:ok, [dir, qty], "\n", %{}, _, _} = M.rotation(line) ; {dir, qty} end)
|> Enum.reduce({50, 0}, fn {dir, qty}, {pos, zeroes} ->
  dist_to_zero = if dir == "L", do: pos, else: Integer.mod(100-pos, 100)
  pos =  Integer.mod(pos + (if dir == "R", do: 1, else: -1) * qty, 100)
  n = div(max(0, qty-dist_to_zero), 100) + (if pos != 0 && qty-dist_to_zero >= 0, do: 1, else: 0)
  {pos, zeroes + n}
end)
|> tap(fn {_pos, zeroes} -> IO.puts("Day 1. Part 2. Number of zeroes: #{zeroes}") 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
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 10 of the Advent of Code 2021. We have a private leaderboard (shared with users of Erlang Forums ): https://adv...
New
bjorng
This topic is about Day 15 of the Advent of Code 2021. We have a private leaderboard (shared with users of Erlang Forums): https://adve...
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
jkwchui
Monkeys fitted squarely as GenServers in my head. My initial problem was using cast instead of call; I imagine impolite monkeys slinging...
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
bjorng
Note: This topic is to talk about Day 5 of the Advent of Code 2019. There is a private leaderboard for elixirforum members. You can join...
New
code-shoily
Just did part 1. Part 2 seems to be demanding too much of my reading time so will get to that after I am done with some chores. Oh here ...
New
maennchen
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

Other popular topics Top

malloryerik
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
New
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
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
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
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
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
JorisKok
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

We're in Beta

About us Mission Statement