bjorng

bjorng

Erlang Core Team

Advent of Code 2025 - Day 2

“When in doubt, use brute force.” – Ken Thompson

defmodule Day02 do
  def part1(input) do
    solve(input, &invalid_part1?/1)
  end

  defp invalid_part1?(n) when is_integer(n) and n > 0 do
    cond do
      n in 10..99 ->
        div(n, 10) === rem(n, 10)
      n in 1000..9999 ->
        div(n, 100) === rem(n, 100)
      n in 100_000..999_999 ->
        div(n, 1000) === rem(n, 1000)
      n in 10_000_000..99_999_999 ->
        div(n, 10_000) === rem(n, 10_000)
      n in 1_000_000_000..9_999_999_999 ->
        div(n, 100_000) === rem(n, 100_000)
      true -> false
    end
  end

  def part2(input) do
    solve(input, &invalid_part2?/1)
  end

  defp invalid_part2?(n) when is_integer(n) and n > 0 do
    powers = [10, 100, 1000, 10000, 100000, 1000000]
    Enum.any?(powers, fn power ->
      part = rem(n, power)
      if part < div(power, 10) do
        false
      else
        case count_parts(div(n, power), power, part, 1) do
          nil -> false
          num_parts -> num_parts >= 2
        end
      end
    end)
  end

  defp count_parts(0, _power, _part, num_parts), do: num_parts
  defp count_parts(n, power, part, num_parts) do
    case rem(n, power) do
      ^part ->
        count_parts(div(n, power), power, part, num_parts + 1)
      _ ->
        nil
    end
  end

  defp solve(input, invalid) do
    parse(input)
    |> Enum.flat_map(&expand_range(&1, invalid))
    |> Enum.sum
  end

  defp expand_range(r, invalid) do
    Enum.flat_map(r, fn n ->
      case invalid.(n) do
        true -> [n]
        false -> []
      end
    end)
  end

  defp parse(input) do
    input
    |> Enum.flat_map(fn line ->
      line
      |> String.split(",")
      |> Enum.map(fn range ->
        range
        |> String.split("-")
        |> then(fn [first, last] ->
          String.to_integer(first) .. String.to_integer(last)
        end)
      end)
    end)
  end
end

Most Liked

lud

lud

Yes brute force is the way :smiley:

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

  def parse(input, _part) do
    input
    |> Input.read!()
    |> String.trim()
    |> String.split(",")
    |> Enum.map(fn range ->
      [left, right] = String.split(range, "-")
      left = String.to_integer(left)
      right = String.to_integer(right)
      left..right
    end)
  end

  def part_one(problem) do
    problem
    |> Stream.flat_map(& &1)
    |> Stream.filter(&invalid_p1?/1)
    |> Enum.sum()
  end

  defp invalid_p1?(n) do
    mirror?(Integer.digits(n))
  end

  defp mirror?([a, a]), do: true
  defp mirror?([a, b, a, b]), do: true
  defp mirror?([a, b, c, a, b, c]), do: true
  defp mirror?([a, b, c, d, a, b, c, d]), do: true
  defp mirror?([a, b, c, d, e, a, b, c, d, e]), do: true
  defp mirror?(_), do: false

  def part_two(problem) do
    problem
    |> Stream.flat_map(& &1)
    |> Stream.filter(&invalid_p2?/1)
    |> Enum.sum()
  end

  defp invalid_p2?(n) do
    repeats?(Integer.digits(n))
  end

  defp repeats?([a, a]), do: true
  defp repeats?([a, a, a]), do: true
  defp repeats?([a, b, a, b]), do: true
  defp repeats?([a, a, a, a, a]), do: true
  defp repeats?([a, b, a, b, a, b]), do: true
  defp repeats?([a, b, c, a, b, c]), do: true
  defp repeats?([a, a, a, a, a, a, a]), do: true
  defp repeats?([a, b, a, b, a, b, a, b]), do: true
  defp repeats?([a, b, c, d, a, b, c, d]), do: true
  defp repeats?([a, a, a, a, a, a, a, a, a]), do: true
  defp repeats?([a, b, c, a, b, c, a, b, c]), do: true
  defp repeats?([a, b, a, b, a, b, a, b, a, b]), do: true
  defp repeats?([a, b, c, d, e, a, b, c, d, e]), do: true
  defp repeats?(_), do: false
end

Edit: I realize now that mirror? is a very incorrect name for that function :smiley:

mudasobwa

mudasobwa

Creator of Cure

No regexes, no magic save for metaprogramming.

  defmodule H do
    def seq(i, count) do
      List.duplicate(
        {:"::", [], [{:seq, [], Elixir}, {:-, [], [{:binary, [], nil}, {:size, [], [i]}]}]},
        count
      )
    end
  end

  defmodule Day2 do
    @input "day2_1.input" |> File.read!() |> String.trim()

    Enum.each(1..100, fn i ->
      def forged_1(<<seq::binary-size(unquote(i)), seq::binary-size(unquote(i))>>), do: 1
    end)

    def forged_1(_), do: 0

    import Aoc2025.H

    for count <- 2..12, i <- 1..100 do
      def forged_2(<<unquote_splicing(seq(i, count))>>), do: 1
    end

    def forged_2(_), do: 0

    def calc(input \\ @input) do
      input
      |> String.split(",", trim: true)
      |> Stream.map(&String.split(&1, "-", trim: true))
      |> Stream.map(fn [b, e] -> String.to_integer(b)..String.to_integer(e) end)
      |> Stream.map(fn range -> Enum.reduce(range, 0, &(&2 + &1 * forged_2("#{&1}"))) end)
      |> Enum.sum()
    end
  end
lud

lud

Yeah of course, but I was in rush so actually I just wrote a loop to print the clauses and then pasted them into the module. Quick and dirty :smiley:

Edit: well that actually counts as metaprogramming :smiley:

Where Next?

Popular in Challenges Top

Aetherus
Hello, guys. I’m back again, but only for the weekends, maybe. This topic is about Day 13 of the Advent of Code 2020 . Thanks to @egze,...
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
ehayun
I have 2 arrays: a1 can be any combination of value or nil like that a1 = [1,nil,3] and array 2 the same a2 = [4,2, nil] How do I com...
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
This topic is about Day 1 of the Advent of Code 2021. We have a private leaderboard (shared with users of Erlang Forums): https://adven...
New
rugyoga
part 1: https://github.com/rugyoga/aoc2021/blob/main/day8.exs part 2: https://github.com/rugyoga/aoc2021/blob/main/day8b.exs
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
stevensonmt
Anyone else think the prompt for this challenge is contradictory? The rules for comparing packets include If both values are lists, c...
New
igorb
Today is a brute-force day: advent-of-code-2024/lib/advent_of_code2024/day6.ex at main · ibarakaiev/advent-of-code-2024 · GitHub Takes a...
New
adamu
Probably not the most efficient implementation, because part 1 took &gt;1 ms and part 2 &gt;4ms, but the code was simple enough. def p...
New

Other popular topics Top

electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
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
hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a &gt; b) do {:ok, "a"} end if (a &lt; b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 39523 209
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 52774 488
New
New

We're in Beta

About us Mission Statement