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

Day 1: Historian Hysteria

2024/day-01.livemd

Day 1: Historian Hysteria

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

Day 1

sample_input = Kino.Input.textarea("Paste Sample Input")
real_input = Kino.Input.textarea("Paste Real Input")
parse = fn input ->
  input
  |> Kino.Input.read()
  |> String.split("\n", trim: true)
  |> Enum.map(fn line ->
    [a, b] = String.split(line, ~r/\s+/)
    {String.to_integer(a), String.to_integer(b)}
  end)
  |> Enum.unzip()
end

sort = fn {list_a, list_b} -> {Enum.sort(list_a), Enum.sort(list_b)} end

add_differences = fn {list_a, list_b} ->
  [list_a, list_b]
  |> Enum.zip_reduce(0, fn [a, b], sum ->
    sum + abs(a - b)
  end)
end

frequencies = fn list ->
  Enum.reduce(list, %{}, fn number, freq ->
    Map.update(freq, number, 1, & &1 + 1)
  end)
end

similarity_score = fn {left, right} ->
  freq = frequencies.(right)
  Enum.reduce(left, 0, fn number, similarity ->
    weight = Map.get(freq, number, 0)
    similarity + weight * number
  end)
end
sample_input |> parse.() |> sort.() |> add_differences.()
real_input |> parse.() |> sort.() |> add_differences.()
sample_input |> parse.() |> similarity_score.()
real_input |> parse.() |> similarity_score.()