Powered by AppSignal & Oban Pro

Day 2

2025/02.livemd

Day 2

Mix.install([
  {:kino_aoc, "~> 0.1"}
])

Setup

{:ok, input} = KinoAOC.download_puzzle("2025", "2", System.fetch_env!("LB_AOC_SESSION"))
{:ok,
 "8123221734-8123333968,2665-4538,189952-274622,4975-9031,24163352-24202932,1233-1772,9898889349-9899037441,2-15,2147801-2281579,296141-327417,8989846734-8989940664,31172-42921,593312-632035,862987-983007,613600462-613621897,81807088-81833878,13258610-13489867,643517-782886,986483-1022745,113493-167913,10677-16867,372-518,3489007333-3489264175,1858-2534,18547-26982,16-29,247-366,55547-103861,57-74,30-56,1670594-1765773,76-129,134085905-134182567,441436-566415,7539123416-7539252430,668-1146,581563513-581619699"}
ex = "11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124"
"11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124"
String.duplicate("ho", 3)
"hohoho"

Solution

defmodule Day2 do
  @regex ~r/^(\d+)\1+$/

  def parse(str) do
    String.split(str, ~r/,/, trim: true) |> Enum.map(fn x ->
      [start_pid, end_pid] = String.split(x,~r/-/)
      String.to_integer(start_pid)..String.to_integer(end_pid)
    end)
  end

  def is_valid?(pid) do
    pid_str = pid |> Integer.to_string()
    pid_len = String.length(pid_str)

    if rem(pid_len, 2) == 1 do
      true
    else
      half = String.slice(pid_str, 0..Integer.floor_div(pid_len - 1,2))
      pid_str != half <> half
    end
  end

  def solve_range(range) do
    range |> Enum.reject(&amp;is_valid?/1) |> Enum.sum()
  end

  def solve(str) do
    parse(str)
      |> Task.async_stream(&amp;solve_range/1)
      |> Enum.reduce(0, fn {:ok, v}, acc -> acc + v end)
  end

  def is_valid2?(pid) do
    Regex.run(@regex, Integer.to_string(pid)) == nil
  end
  
  def solve_range2(range) do
    range |> Enum.reject(&amp;is_valid2?/1) |> Enum.sum()
  end

  def solve2(str) do
    parse(str)
      |> Task.async_stream(&amp;solve_range2/1)
      |> Enum.reduce(0, fn {:ok, v}, acc -> acc + v end)
  end

end
{:module, Day2, <<70, 79, 82, 49, 0, 0, 18, ...>>, {:solve2, 1}}

Part 1

Day2.parse(ex)
[11..22, 95..115, 998..1012, 1188511880..1188511890, 222220..222224, 1698522..1698528,
 446443..446449, 38593856..38593862, 565653..565659, 824824821..824824827, 2121212118..2121212124]
Day2.is_valid?(11)
false
Day2.is_valid?(101)
true
Day2.is_valid?(110)
true
Day2.solve(ex)
1227775554
Day2.solve(input)
55916882972

Part 2

Day2.is_valid2?(12)
true
Day2.is_valid2?(111)
false
Day2.solve2(input)
76169125915