Advent of Code 2024/5
Mix.install([
{:kino, "~> 0.14.2"}
])
Section
input = Kino.Input.textarea("input")
defmodule AoC2024_5 do
def convert(lists) do
Enum.map(lists, fn list -> Enum.map(list, fn el -> String.to_integer(el) end) end)
end
def parse(input) do
Kino.Input.read(input)
|> String.split("\n\n", trim: true)
|> Enum.map(fn part -> String.split(part, "\n", trim: true) end)
|> (fn [a, b] -> [
b |> Enum.map(fn item -> String.split(item, ",", trim: true) end) |> convert,
a |> Enum.map(fn item -> String.split(item, "|", trim: true) end) |> convert
] end).()
end
def slice_set(set, 0), do: [[], Enum.slice(set, 1..(length(set)-1))]
def slice_set(set, index) when length(set) - 1 == index, do: [Enum.slice(set, 0..(length(set)-2)), []]
def slice_set(set, index) do
[
Enum.slice(set, 0..(index - 1)),
Enum.slice(set, (index + 1)..(length(set) - 1))
]
end
def valid_page({page, index}, set, rules) do
[before_set, after_set] = slice_set(set, index)
after_pages = Enum.filter(rules, fn rule -> Enum.at(rule, 0) == page end) |> Enum.map(fn rule -> Enum.at(rule, 1) end)
before_pages = Enum.filter(rules, fn rule -> Enum.at(rule, 1) == page end) |> Enum.map(fn rule -> Enum.at(rule, 0) end)
MapSet.disjoint?(MapSet.new(before_set), MapSet.new(after_pages)) && MapSet.disjoint?(MapSet.new(after_set), MapSet.new(before_pages))
end
def part_1(input) do
[page_sets, rules] = input
|> parse
page_sets
|> Enum.filter(fn set -> !Enum.any?(Enum.with_index(set), fn page -> !valid_page(page, set, rules) end) end)
|> Enum.map(fn set -> Enum.at(set, div(length(set),2)) end)
|> Enum.sum
end
def before_by_rules(first, second, rules) do
length(Enum.filter(rules, fn rule -> Enum.at(rule, 0) == first && Enum.at(rule, 1) == second end)) > 0
end
def part_2(input) do
[page_sets, rules] = input
|> parse
page_sets
|> Enum.filter(fn set -> Enum.any?(Enum.with_index(set), fn page -> !valid_page(page, set, rules) end) end)
|> Enum.map(fn set -> Enum.sort(set, &(before_by_rules(&1, &2, rules))) end)
|> Enum.map(fn set -> Enum.at(set, div(length(set),2)) end)
|> Enum.sum
end
end
AoC2024_5.part_1(input)
AoC2024_5.part_2(input)