Powered by AppSignal & Oban Pro

Advent of code 2025 day 2

aoc2025day2.livemd

Advent of code 2025 day 2

Mix.install([
  {:kino, "~> 0.18"}
])

Part 1

https://adventofcode.com/2025/day/2

input = Kino.Input.textarea("Please give me input:")
product_id_ranges =
  Kino.Input.read(input)
  |> String.split(",", trim: true)
  |> Enum.map(fn product_id_range ->
    [from, to] = String.split(product_id_range, "-")
    {String.to_integer(from), String.to_integer(to)}
    end)

length(product_id_ranges)
defmodule Part1 do
  def check_range(from, to) do
    Enum.filter(from..to, fn product_id ->
      split_this = Integer.to_string(product_id)
      full_length = String.length(split_this)

      if full_length > 1 and rem(full_length, 2) == 0 do
        {first_half, second_half} = String.split_at(split_this, div(full_length, 2))
        first_half == second_half
      else
        false
      end
    end)
  end

  def check_ranges(product_id_ranges) do
    Enum.reduce(product_id_ranges, [], fn {from, to}, acc ->
      [check_range(from, to) | acc]
    end)
  end
end

Part1.check_ranges(product_id_ranges) |> List.flatten |> Enum.sum

Part 2

defmodule Part2 do
  def divisions(len) when len <= 1, do: []

  def divisions(len) do
    Enum.filter(1..div(len, 2), fn division -> rem(len, division) == 0 end)
  end

  def check_range(from, to) do
    Enum.filter(from..to, fn product_id ->
      split_this = Integer.to_string(product_id)
      full_length = String.length(split_this)
      list_of_slice_lengths = divisions(full_length)

      Enum.reduce_while(list_of_slice_lengths, false, fn slice_length, _acc ->
        first = String.slice(split_this, 0, slice_length)
        total = String.duplicate(first, div(full_length, slice_length))
        found = (split_this == total)

        if found do
          {:halt, true}
        else
          {:cont, false}
        end
      end)
    end)
  end

  def check_ranges(product_id_ranges) do
    Enum.reduce(product_id_ranges, [], fn {from, to}, acc ->
      [check_range(from, to) | acc]
    end)
  end
end

Part2.check_ranges(product_id_ranges) |> List.flatten() |> Enum.sum()