Solve day 5

This commit is contained in:
Aurélien Geron
2024-12-09 10:19:50 +13:00
parent 499a6f145d
commit 9808ad404c
3 changed files with 89 additions and 14 deletions
+39 -5
View File
@@ -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
View File
@@ -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