feat: pass the tests

This commit is contained in:
Ruidy 2024-12-05 11:10:27 +01:00
parent 901ad6c645
commit d742148e96
No known key found for this signature in database
GPG key ID: E00F51288CB857CC
3 changed files with 1476 additions and 13 deletions

View file

@ -1,4 +1,4 @@
defmodule AdventCode2024.Solutions.Day5 do
defmodule AdventCode2024.Solutions.Day05 do
@moduledoc """
Day 5: Solution for Advent of Code 2024
"""
@ -38,9 +38,13 @@ defmodule AdventCode2024.Solutions.Day5 do
defp solve_content(""), do: {:error, :no_input}
defp solve_content(content) when is_binary(content) and content != "" do
{rules, updates} = parse_input(content)
result =
content
|> parse_input()
updates
|> Enum.filter(&is_valid_update?(&1, rules))
|> Enum.map(&get_middle_number/1)
|> Enum.sum()
{:ok, result}
end
@ -56,7 +60,56 @@ defmodule AdventCode2024.Solutions.Day5 do
end
defp parse_input(input) do
input
[rules_section, updates_section] = String.split(input, "\n\n", trim: true)
rules = parse_rules(rules_section)
updates = parse_updates(updates_section)
{rules, updates}
end
defp parse_rules(rules_section) do
rules_section
|> String.split("\n", trim: true)
|> Enum.map(fn rule ->
[first, second] = String.split(rule, "|")
{String.to_integer(first), String.to_integer(second)}
end)
end
defp parse_updates(updates_section) do
updates_section
|> String.split("\n", trim: true)
|> Enum.map(fn update ->
update
|> String.split(",", trim: true)
|> Enum.map(&String.to_integer/1)
end)
end
defp is_valid_update?(update, rules) do
# For each pair of numbers in the update, check if they satisfy all applicable rules
update
|> Enum.with_index()
|> Enum.all?(fn {num1, idx1} ->
update
|> Enum.with_index()
|> Enum.all?(fn {num2, idx2} ->
# Only check pairs where the second number comes after the first
if idx2 > idx1 do
# Check if there's a rule requiring num2 to come before num1
not Enum.any?(rules, fn {first, second} ->
num1 == second and num2 == first
end)
else
true
end
end)
end)
end
defp get_middle_number(update) do
middle_index = div(length(update), 2)
Enum.at(update, middle_index)
end
end

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
defmodule AdventCode2024.Solutions.Day5Test do
defmodule AdventCode2024.Solutions.Day05Test do
use ExUnit.Case
alias AdventCode2024.Solutions.Day5
alias AdventCode2024.Solutions.Day05
@example_input """
47|53
@ -33,17 +33,30 @@ defmodule AdventCode2024.Solutions.Day5Test do
97,13,75,29,47
"""
setup_all do
# Create a temporary file for testing
path = "test/fixtures/day05/test_input.txt"
File.mkdir_p!(Path.dirname(path))
:ok = File.write(path, @example_input)
on_exit(fn ->
File.rm!(path)
end)
{:ok, test_file: path}
end
describe "solve/1" do
test "correctly identifies valid updates and sums middle pages" do
assert {:ok, 143} = Day5.solve_content(@example_input)
test "correctly identifies valid updates and sums middle pages", %{test_file: path} do
assert {:ok, 143} = Day05.solve(path)
end
test "returns error for empty input" do
assert Day5.solve("") == {:error, :no_input}
assert Day05.solve("") == {:error, :no_input}
end
test "returns error for invalid file" do
assert Day5.solve("priv/nonexistent.txt") == {:error, :enoent}
assert Day05.solve("priv/nonexistent.txt") == {:error, :enoent}
end
test "validates first update is in correct order" do
@ -61,7 +74,11 @@ defmodule AdventCode2024.Solutions.Day5Test do
75,47,61,53,29
"""
assert {:ok, 61} = Day5.solve_content(input)
path = "test/fixtures/day05/first_update.txt"
:ok = File.write(path, input)
assert {:ok, 61} = Day05.solve(path)
File.rm!(path)
end
test "validates second update is in correct order" do
@ -78,7 +95,11 @@ defmodule AdventCode2024.Solutions.Day5Test do
97,61,53,29,13
"""
assert {:ok, 53} = Day5.solve_content(input)
path = "test/fixtures/day05/second_update.txt"
:ok = File.write(path, input)
assert {:ok, 53} = Day05.solve(path)
File.rm!(path)
end
test "identifies invalid update due to rule violation" do
@ -87,7 +108,11 @@ defmodule AdventCode2024.Solutions.Day5Test do
75,97,47,61,53
"""
assert {:ok, 0} = Day5.solve_content(input)
path = "test/fixtures/day05/invalid_update.txt"
:ok = File.write(path, input)
assert {:ok, 0} = Day05.solve(path)
File.rm!(path)
end
end
end