1
0
Fork 0
advent-of-code/2021/lib/mix/tasks/advent_of_code.solve.ex
Sloane Perrault a691461882 Setup 2021 (#1)
* chore: scaffold project

* chore: stand up puzzle solver, puzzle case

* feat: solution runner

* feat: solution generator
2022-09-21 09:19:53 -04:00

73 lines
1.8 KiB
Elixir

defmodule Mix.Tasks.AdventOfCode.Solve do
use Mix.Task
@shortdoc "Runs solution code with problem input"
@moduledoc """
#{@shortdoc}.
## Options
`--input`
- name of a `.input` file in `priv/inputs/` without the `.input` extension or `-` to read from stdin
## Examples
# Run Day 2, Part 1 solution program against the `2.1.input` file
$ mix advent_of_code.solve 2.1
# Run Day 1, Part 2 with a special input
$ mix advent_of_code.solve 1.2 --input day-1-part-2-small # priv/inputs/day-1-part-2-small.input
# Run Day 17, Part 1 with input from stdin
# $ mix advent_of_code.solve 17.1 --input -
"""
@switches [input: :string]
@impl Mix.Task
def run(args) do
case OptionParser.parse!(args, strict: @switches) do
{opts, [selector]} ->
case stream_for_input(selector, opts) do
{:indeterminate, stream} ->
ProgressBar.render_spinner(
[text: "Processing indeterminate data...", done: "Done."],
fn -> solve(selector, stream) end
)
|> IO.puts()
{size, stream} ->
stream =
stream
|> Stream.with_index(1)
|> Stream.each(fn {_, i} -> ProgressBar.render(i, size) end)
|> Stream.map(fn {l, _} -> l end)
solve(selector, stream)
|> IO.puts()
end
_ ->
nil
end
end
defp solve(selector, stream) do
selector
|> AdventOfCode.solver()
|> AdventOfCode.PuzzleSolver.solve(stream)
end
defp stream_for_input(selector, opts) do
input = Keyword.get(opts, :input, selector)
if input == "-" do
{:indeterminate, IO.stream()}
else
file = Path.join("priv/inputs", "#{input}.input")
stream = File.stream!(file)
{Enum.count(stream), stream}
end
end
end