Advent of Code 2024 Day 5 Part 2
Mix.install([
{:kino_aoc, "~> 0.1"}
])
Get Inputs
{:ok, puzzle_input} =
KinoAOC.download_puzzle("2024", "5", System.fetch_env!("LB_SESSION"))
My answer
parse_input = fn input ->
[rules, updates] =
input
|> String.split("\n\n")
|> Enum.map(&String.split(&1, "\n"))
rules =
rules
|> Enum.map(fn rule ->
rule
|> String.split("|")
|> Enum.map(&String.to_integer(&1))
|> List.to_tuple()
end)
updates =
updates
|> Enum.map(fn update ->
update
|> String.split(",")
|> Enum.map(&String.to_integer(&1))
end)
{rules, updates}
end
{rules, updates} =
"""
47|53
97|13
97|61
97|47
75|29
61|13
75|53
29|13
97|29
53|29
61|53
97|53
61|29
47|13
75|47
97|75
47|61
75|61
47|29
75|13
53|13
75,47,61,53,29
97,61,53,29,13
75,29,13
75,97,47,61,53
61,13,29
97,13,75,29,47
"""
|> String.trim()
|> parse_input.()
defmodule Fixer do
def get_wrong_updates(updates, rules) do
updates
|> Enum.filter(fn update ->
rules
|> Enum.reduce_while(nil, fn {a, b}, _ ->
a_index = Enum.find_index(update, &(&1 ==a))
b_index = Enum.find_index(update, &(&1 ==b))
if is_nil(a_index) or is_nil(b_index) do
{:cont, true}
else
if a_index < b_index do
{:cont, true}
else
{:halt, false}
end
end
end)
|> then(&(not &1))
end)
end
def fix_update(update, rules) do
rules
|> Enum.reduce(update, fn {a, b}, acc_update ->
a_index = Enum.find_index(acc_update, &(&1 ==a))
b_index = Enum.find_index(acc_update, &(&1 ==b))
if is_nil(a_index) or is_nil(b_index) do
acc_update
else
if a_index < b_index do
acc_update
else
acc_update
|> List.update_at(a_index, fn _ -> b end)
|> List.update_at(b_index, fn _ -> a end)
|> fix_update(rules)
end
end
end)
end
end
updates
|> Fixer.get_wrong_updates(rules)
|> Enum.map(fn update ->
Fixer.fix_update(update, rules)
end)
|> Enum.map(fn update ->
Enum.at(update, div(length(update), 2))
end)
|> Enum.sum()
{rules, updates} = parse_input.(puzzle_input)
updates
|> Fixer.get_wrong_updates(rules)
|> Enum.map(fn update ->
Fixer.fix_update(update, rules)
end)
|> Enum.map(fn update ->
Enum.at(update, div(length(update), 2))
end)
|> Enum.sum()