Powered by AppSignal & Oban Pro

Advent of code day 05

2025/livebooks/day-05.livemd

Advent of code day 05

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

Setup input

example = Kino.Input.textarea("Please paste your input example:")
input = Kino.Input.textarea("Please paste your real input:")
[ranges | [ids | []]] =
  example
  |> Kino.Input.read()
  |> String.split("\n\n")

rangess =
  ranges
  |> String.split("\n", trim: true)
  |> Enum.map(fn x ->
    String.split(x, "-", trim: true)
    |> Enum.map(&String.to_integer/1)
  end)
  |> Enum.map(fn [x, y] -> x..y end)

ids =
  ids
  |> String.split("\n", trim: true)
  |> Enum.map(&String.to_integer/1)

Part 01

Enum.reduce(ids, 0, fn id, acc ->
  case Enum.any?(rangess, fn range -> id in range end) do
    false -> acc
    true -> acc + 1
  end
end)

Part 02

[start | tail] =
  ranges =
  ranges
  |> String.split("\n", trim: true)
  |> Enum.map(fn x ->
    String.split(x, "-", trim: true)
    |> Enum.map(&String.to_integer/1)
  end)
  |> Enum.sort_by(fn [start, _nd] -> start end)

# merge intervals, leetcode classical
Enum.reduce(tail, {start}, fn [cs, cf], output ->
  index = tuple_size(output) - 1
  [lastStart, lastEnd] = elem(output, index)

  if cs <= lastEnd do
    output |> Tuple.delete_at(index) |> Tuple.insert_at(index, [lastStart, max(cf, lastEnd)])
  else
    Tuple.insert_at(output, index + 1, [cs, cf])
  end
end)
|> Tuple.to_list()
# inclusive 
|> Enum.map(fn [s, e] -> e - s + 1 end)
|> Enum.sum()