90 lines
2.2 KiB
Elixir
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
|