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

Day 05

2024/day_05.livemd

Day 05

Mix.install([:kino_aoc])

Kino.configure(inspect: [charlists: :as_lists])

Input

{:ok, puzzle_input} =
  KinoAOC.download_puzzle("2024", "5", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
[rules, updates] = String.split(puzzle_input, "\n\n") |> Enum.map(&String.split(&1, "\n"))

rules = Enum.map(rules, &String.split(&1, "|")) |> Enum.group_by(&Enum.at(&1, 1), &Enum.at(&1, 0))
updates = Enum.map(updates, &String.split(&1, ","))

Part 1

Enum.filter(updates, fn line -> 
  Enum.all?(Stream.with_index(line), fn {num, index} -> 
    not Enum.any?(Enum.slice(line, index+1..-1//1), fn x -> 
      Enum.member?(rules[num] || [], x)
    end)
  end)
end)
|> Enum.reduce(0, fn line, acc -> 
  acc + String.to_integer(Enum.at(line, div(length(line), 2))) 
end)

Part 2

Enum.filter(updates, fn line -> 
  Enum.any?(Stream.with_index(line), fn {num, index} -> 
    Enum.any?(Enum.slice(line, index+1..-1//1), fn x -> 
      Enum.member?(rules[num] || [], x)
    end)
  end)
end)
|> Enum.map(fn line -> Enum.sort(line, fn x, y -> 
    Enum.member?(rules[y] || [], x) or x == y
  end)
end)
|> Enum.reduce(0, fn line, acc -> 
  acc + String.to_integer(Enum.at(line, div(length(line), 2))) 
end)