Solve day 5
This commit is contained in:
+39
-5
@@ -1,13 +1,47 @@
|
||||
defmodule Aoc2024.Day05 do
|
||||
def parse(input) do
|
||||
input |> String.split("\n", trim: true)
|
||||
[rules_raw, updates_raw] = input |> String.trim() |> String.split("\n\n")
|
||||
rules = Aoc2024.Utils.parse_rows_of_integers(rules_raw, "|")
|
||||
updates = Aoc2024.Utils.parse_rows_of_integers(updates_raw, ",")
|
||||
{rules, updates}
|
||||
end
|
||||
|
||||
def part1(_lines) do
|
||||
:todo1
|
||||
defp sort([], _rules), do: %{was_sorted?: true, list: []}
|
||||
|
||||
defp sort([head | tail], rules) do
|
||||
result =
|
||||
tail
|
||||
|> Enum.reduce(%{sorted?: true, revlist: [], previous: head}, fn elem, acc ->
|
||||
if rules |> Enum.member?([elem, acc.previous]) do
|
||||
%{sorted?: false, revlist: [elem | acc.revlist], previous: acc.previous}
|
||||
else
|
||||
%{sorted?: acc.sorted?, revlist: [acc.previous | acc.revlist], previous: elem}
|
||||
end
|
||||
end)
|
||||
|
||||
partially_sorted = [result.previous | result.revlist] |> Enum.reverse()
|
||||
|
||||
if result.sorted? do
|
||||
%{was_sorted?: true, list: partially_sorted}
|
||||
else
|
||||
%{was_sorted?: false, list: sort(partially_sorted, rules).list}
|
||||
end
|
||||
end
|
||||
|
||||
def part2(_lines) do
|
||||
:todo2
|
||||
def part1({rules, updates}) do
|
||||
updates
|
||||
|> Enum.filter(fn update -> sort(update, rules).was_sorted? end)
|
||||
|> Enum.map(fn update -> update |> Enum.at(length(update) |> div(2)) end)
|
||||
|> Enum.sum()
|
||||
end
|
||||
|
||||
def part2({rules, updates}) do
|
||||
updates
|
||||
|> Enum.map(fn update -> sort(update, rules) end)
|
||||
|> Enum.filter(fn sort_result -> not sort_result.was_sorted? end)
|
||||
|> Enum.map(fn sort_result ->
|
||||
sort_result.list |> Enum.at(length(sort_result.list) |> div(2))
|
||||
end)
|
||||
|> Enum.sum()
|
||||
end
|
||||
end
|
||||
|
||||
+13
-9
@@ -1,16 +1,20 @@
|
||||
defmodule Aoc2024.Utils do
|
||||
def parse_rows_of_integers(input) do
|
||||
def parse_integers(input, separator \\ ~r/\s+/) do
|
||||
input
|
||||
|> String.split(separator)
|
||||
|> Enum.map(fn int_str ->
|
||||
case int_str |> Integer.parse() do
|
||||
{int, ""} -> int
|
||||
_ -> raise "Invalid integer #{int_str}"
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
def parse_rows_of_integers(input, separator \\ ~r/\s+/) do
|
||||
input
|
||||
|> String.split("\n", trim: true)
|
||||
|> Enum.map(fn line ->
|
||||
line
|
||||
|> String.split(~r/\s+/)
|
||||
|> Enum.map(fn int_str ->
|
||||
case int_str |> Integer.parse() do
|
||||
{int, ""} -> int
|
||||
_ -> raise "Invalid integer #{int_str}"
|
||||
end
|
||||
end)
|
||||
parse_integers(line, separator)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -70,4 +70,41 @@ defmodule Aoc2024Test do
|
||||
assert Aoc2024.Day04.part1(parsed_input) == 18
|
||||
assert Aoc2024.Day04.part2(parsed_input) == 9
|
||||
end
|
||||
|
||||
test "Day 5" do
|
||||
input = """
|
||||
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
|
||||
"""
|
||||
|
||||
parsed_input = Aoc2024.Day05.parse(input)
|
||||
assert Aoc2024.Day05.part1(parsed_input) == 143
|
||||
assert Aoc2024.Day05.part2(parsed_input) == 123
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user