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

AoC 2024/01

aoc-2024-01.livemd

AoC 2024/01

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

Section

input = Kino.Input.textarea("input")
defmodule Day1 do
  defp parse_input(input) do
    input |> String.split("\n")
    |> Enum.map(fn str -> 
      [left_str, right_str] = String.split(str, "   ")
      [String.to_integer(left_str), String.to_integer(right_str)]
    end)
  end

  def solve1(input) do
    parse_input(input)
    |> transpose()
    |> distances()
    |> Enum.sum()
  end

  defp transpose(list_of_lists) do
    Enum.zip_with(list_of_lists, &Function.identity/1)
  end

  defp columns(list_of_pairs) do
    {_left_col, _right_col} = list_of_pairs
     |> Enum.reduce({[], []}, fn [left, right], {lefts, rights} ->
       {[left | lefts], [right | rights]}
    end)
  end

  defp distances([left_column, right_column]) do
    Enum.zip(Enum.sort(left_column), Enum.sort(right_column))
    |> Enum.map(fn {left, right} -> abs(left - right) end)
  end

  def solve2(input) do
    input
    |> parse_input()
    |> columns()
    |> similarity_score()
    |> Enum.sum()
  end

   defp similarity_score({left_column, right_column}) do
     right_frequencies = Enum.frequencies(right_column)
     
     left_column
     |> Enum.map(fn left -> 
       left * Map.get(right_frequencies, left, 0)
     end)
   end
end
{:module, Day1, <<70, 79, 82, 49, 0, 0, 14, ...>>, {:similarity_score, 1}}
Kino.Input.read(input)
|> Day1.solve1()
1889772
Kino.Input.read(input)
|> Day1.solve2()
23228917
str = "66845   37619"
String.split(str, "   ")
["66845", "37619"]