Advent of Code 2024 - Day 5

LOC: 21
EDIT: 19 (found a shorter reorder)

defmodule Aoc2024.Day05 do
  def part1(file), do: file |> main() |> elem(0)
  def part2(file), do: file |> main() |> elem(1)

  def main(file) do
    {orders, [_ | updates]} = file |> file_to_lines |> Enum.split_while(&(&1 != ""))
    orders = orders |> Enum.map(&to_integers(&1, "|")) |> Enum.group_by(&hd/1, &List.last/1)
    updates = Enum.map(updates, &to_integers(&1, ","))
    {corrects, incorrects} = Enum.split_with(updates, &c?(Enum.reverse(&1), orders))
    {sum_middles(corrects), sum_middles(Enum.map(incorrects, &reorder(&1, orders, [])))}
  end

  def file_to_lines(file), do: file |> File.read!() |> String.trim() |> String.split("\n")
  def to_integers(line, sep), do: line |> String.split(sep) |> Enum.map(&String.to_integer/1)
  def sum_middles(lists), do: lists |> Enum.map(&Enum.at(&1, div(length(&1), 2))) |> Enum.sum()
  def c?([h | t], o), do: if(Enum.any?(t, &(&1 in Map.get(o, h, []))), do: false, else: c?(t, o))
  def c?([], _), do: true
  def reorder(l, o), do: Enum.sort(l, &(&2 in Map.get(o, &1, [])))
end