Files
Aurélien Geron adfaafec83 Initial release
2024-12-06 19:44:29 +13:00

90 lines
2.2 KiB
Elixir

defmodule Mix.Tasks.Aoc2024.Run do
use Mix.Task
@shortdoc "Run all the solutions, or just the ones for the given days"
def run(args) do
days =
if args |> Enum.empty?() do
1..25 |> Enum.map(&Integer.to_string/1)
else
args
end
days |> Enum.each(&run_day/1)
end
defp check_and_pad_day(day_str) do
case day_str |> Integer.parse() do
{day, ""} when day >= 1 and day <= 25 ->
IO.puts("---- Day #{day}")
{:ok, day |> Integer.to_string() |> String.pad_leading(2, "0")}
_ ->
{:error, "Invalid day `#{day_str}`"}
end
end
defp load_module(padded_day_str) do
module = Module.concat([Aoc2024, "Day#{padded_day_str}"])
if match?({:module, _}, Code.ensure_loaded(module)) do
{:ok, module}
else
{:error, "Module `#{inspect(module)}` is not defined."}
end
end
defp load_input(padded_day_str) do
file_path = "data/day_#{padded_day_str}.txt"
case File.read(file_path) do
{:ok, content} ->
{:ok, content}
{:error, reason} ->
{:error, "Failed to read #{file_path}: #{reason}"}
end
end
defp parse_input(module, input) do
if function_exported?(module, :parse, 1) do
{:ok, module.parse(input)}
else
{:ok, input}
end
end
defp run_part1(module, parsed) do
if function_exported?(module, :part1, 1) do
result1 = module.part1(parsed)
IO.inspect(result1)
{:ok, true}
else
{:error, "Function `#{inspect(module)}.part1/1` is not defined."}
end
end
defp run_part2(module, parsed) do
if function_exported?(module, :part2, 1) do
result2 = module.part2(parsed)
IO.inspect(result2)
{:ok, true}
else
{:error, "Function `#{inspect(module)}.part2/1` is not defined."}
end
end
defp run_day(day_str) do
with {:ok, padded_day_str} <- check_and_pad_day(day_str),
{:ok, module} <- load_module(padded_day_str),
{:ok, input} <- load_input(padded_day_str),
{:ok, parsed_input} <- parse_input(module, input),
{:ok, _success} <- run_part1(module, parsed_input),
{:ok, _success} <- run_part2(module, parsed_input) do
else
{:error, msg} ->
IO.puts("Error: #{msg}")
end
end
end