Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Advent of Code 2024 Day 9 Part 1

2024_day9_part1.livemd

Advent of Code 2024 Day 9 Part 1

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

Get Inputs

{:ok, puzzle_input} =
  KinoAOC.download_puzzle("2024", "9", System.fetch_env!("LB_SESSION"))

My answer

sample_input = "2333133121414131402"
get_blocks = fn input ->
  input
  |> String.codepoints()
  |> Enum.with_index()
  |> Enum.reduce({[], 0}, fn {num, index}, {acc_list, acc_num_blanck} ->
    num = String.to_integer(num)

    {id, num_blanck} =
      case rem(index, 2) do
        0 ->
          {div(index, 2), 0}
        _ ->
          {nil, num}
      end

    {
      acc_list ++ List.duplicate(id, num),
      acc_num_blanck + num_blanck
    }
  end)
end
{blocks, num_blank} = get_blocks.(sample_input)
compact = fn blocks, num_blank ->
  1..num_blank
  |> Enum.reduce_while(Enum.reverse(blocks), fn _, acc_blocks ->
    case acc_blocks |> Enum.reverse() |> Enum.find_index(&(is_nil(&1))) do
      nil ->
        {:halt, acc_blocks}
      index ->
        blank_index = length(acc_blocks) - 1 - index
  
        {
          :cont,
          acc_blocks
          |> List.update_at(blank_index, fn _ -> hd(acc_blocks) end)
          |> tl()
        }
    end
  end)
  |> Enum.reverse()
end
compacted_blocks = compact.(blocks, num_blank)
get_checksum = fn blocks ->
  blocks
  |> Enum.with_index()
  |> Enum.map(fn {num, index} ->
    num * index
  end)
  |> Enum.sum()
end
get_checksum.(compacted_blocks)
{blocks, num_blank} = get_blocks.(puzzle_input)
compacted_blocks = compact.(blocks, num_blank)
get_checksum.(compacted_blocks)