Day 05
Section
example = """
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
"""
defmodule Day05 do
def part1(input) do
{map, rows} = parse_input(input)
rows
|> Enum.filter(&check_row(&1, map))
|> sum_middle()
end
def part2(input) do
{map, rows} = parse_input(input)
rows
|> Enum.reject(&check_row(&1, map))
|> Enum.map(fn row -> Enum.sort(row, &Map.has_key?(map, {&1, &2})) end)
|> sum_middle()
end
def parse_input(input) do
[raw_rules, raw_updates] = String.split(input, "\n\n", trim: true)
map =
raw_rules
|> String.split("\n", trim: true)
|> Map.new(
&{
String.split(&1, "|", trim: true) |> List.to_tuple(),
true
}
)
rows =
raw_updates
|> String.split("\n", trim: true)
|> Enum.map(&String.split(&1, ",", trim: true))
{map, rows}
end
def sum_middle(row) do
row
|> Enum.map(&Enum.at(&1, div(length(&1), 2)))
|> Enum.map(&String.to_integer/1)
|> Enum.sum()
end
def check_row([], _), do: true
def check_row([h | tail], map), do: check_items(h, tail, map) && check_row(tail, map)
def check_items(_c, [], _map), do: true
def check_items(c, [h | tail], map), do: Map.has_key?(map, {c, h}) && check_items(c, tail, map)
end
IO.puts(Day05.part1(example))
IO.puts(Day05.part2(example))