Infra
This commit is contained in:
12
lib/aoc2023.ex
Normal file
12
lib/aoc2023.ex
Normal file
@@ -0,0 +1,12 @@
|
||||
defmodule Aoc2023 do
|
||||
defmacro __using__([]) do
|
||||
quote do
|
||||
import Aoc2023.Common
|
||||
def main(input) do
|
||||
parsed = parse(input)
|
||||
IO.puts "Part 1: #{part1 parsed}"
|
||||
IO.puts "Part 2: #{part2 parsed}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
3
lib/common.ex
Normal file
3
lib/common.ex
Normal file
@@ -0,0 +1,3 @@
|
||||
defmodule Aoc2023.Common do
|
||||
|
||||
end
|
||||
6
lib/day1.ex
Normal file
6
lib/day1.ex
Normal file
@@ -0,0 +1,6 @@
|
||||
defmodule Aoc2023.Day1 do
|
||||
use Aoc2023
|
||||
def parse(input) do input end
|
||||
def part1(input) do nil end
|
||||
def part2(input) do nil end
|
||||
end
|
||||
124
lib/mix_tasks.ex
Normal file
124
lib/mix_tasks.ex
Normal file
@@ -0,0 +1,124 @@
|
||||
defmodule Mix.Tasks.Aoc do
|
||||
use Mix.Task
|
||||
|
||||
defp module(1), do: Aoc2023.Day1
|
||||
# [MODULE INSERTION POINT]
|
||||
|
||||
defp base_dir(), do: System.get_env("AOC_BASE")
|
||||
|
||||
defp tests(day) do
|
||||
File.ls!(tests_dir(day)) |> Enum.filter(&(not String.contains?(&1, ".")))
|
||||
end
|
||||
|
||||
defp read(path) do
|
||||
f = File.open!(path, [:utf8])
|
||||
contents = IO.read(f, :eof)
|
||||
:ok = File.close(f)
|
||||
contents
|
||||
end
|
||||
|
||||
defp test(day, test) do
|
||||
f = "#{tests_dir(day)}#{test}"
|
||||
{
|
||||
test,
|
||||
read(f),
|
||||
if File.exists?(f <> ".1") do read(f <> ".1") else nil end,
|
||||
if File.exists?(f <> ".2") do read(f <> ".2") else nil end
|
||||
}
|
||||
end
|
||||
|
||||
defp tests_dir(day), do: "#{base_dir()}/tests/day#{day}/"
|
||||
|
||||
defp create_file(path, contents) do
|
||||
File.mkdir_p!(Path.dirname(path))
|
||||
f = File.open!(path, [:exclusive, :utf8])
|
||||
IO.write(f, contents)
|
||||
:ok = File.close(f)
|
||||
end
|
||||
|
||||
def run(params) do
|
||||
{opts, params} = params |> OptionParser.parse!(strict: [day: :integer])
|
||||
day = opts |> Keyword.get(:day, Date.utc_today().day)
|
||||
run(day, params)
|
||||
end
|
||||
|
||||
defp run(day, ["new"]) do
|
||||
create_file("#{base_dir()}/lib/day#{day}.ex", """
|
||||
defmodule Aoc2023.Day#{day} do
|
||||
use Aoc2023
|
||||
def parse(input) do
|
||||
input
|
||||
end
|
||||
def part1(input) do
|
||||
input
|
||||
end
|
||||
def part2(input) do
|
||||
input
|
||||
end
|
||||
end
|
||||
""")
|
||||
this_file = "#{base_dir()}/lib/mix_tasks.ex"
|
||||
contents = read(this_file) |> String.replace("\n # [MODULE INSERTION POINT]", "\n defp module(#{day}), do: Aoc2023.Day#{day}\n # [MODULE INSERTION POINT]")
|
||||
f = File.open!(this_file, [:write, :utf8])
|
||||
IO.write(f, contents)
|
||||
:ok = File.close(f)
|
||||
end
|
||||
|
||||
defp run(day, ["test", "new"]) do
|
||||
last = tests(day) |> Enum.map(&String.to_integer(&1)) |> Enum.max(empty_fallback: fn -> 1 end)
|
||||
create_file("#{tests_dir(day)}#{last + 1}", IO.read(:stdio, :eof))
|
||||
end
|
||||
defp run(day, ["test", "expected", test, part]) do
|
||||
create_file("#{tests_dir(day)}#{test}.#{part}", IO.read(:stdio, :eof))
|
||||
end
|
||||
|
||||
defp run(day, ["test"]) do
|
||||
mod = module(day)
|
||||
tests = tests(day)
|
||||
tests |> Enum.map(&(test(day, &1))) |> Enum.map(fn ({test, input, p1e, p2e}) ->
|
||||
parsed = mod.parse(input)
|
||||
p1 = mod.part1(parsed)
|
||||
if p1e do
|
||||
if to_string(p1) != p1e do
|
||||
IO.puts "Failed at #{test}.1: expected #{p1e}, got:"
|
||||
dbg(p1)
|
||||
end
|
||||
else
|
||||
IO.puts "Test #{test}.1"
|
||||
dbg(p1)
|
||||
end
|
||||
p2 = mod.part2(parsed)
|
||||
if p2e do
|
||||
if to_string(p2) != p2e do
|
||||
IO.puts "Failed at #{test}.2: expected #{p2e}, got:"
|
||||
dbg(p2)
|
||||
end
|
||||
else
|
||||
IO.puts "Test #{test}.2"
|
||||
dbg(p2)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
defp run(day, ["run"]) do
|
||||
run(day, ["fetch"])
|
||||
run_file(day, "#{base_dir()}/inputs/day#{day}")
|
||||
end
|
||||
|
||||
defp run(day, ["run", "-"]) do
|
||||
run_file(day)
|
||||
end
|
||||
|
||||
defp run(day, ["fetch"]) do
|
||||
file = "#{base_dir()}/inputs/day#{day}"
|
||||
if not File.exists? file do
|
||||
HTTPoison.start()
|
||||
resp = HTTPoison.get!("https://adventofcode.com/2023/day/#{day}/input", [ "user-agent": "aoc-ex by ben@soroos.net", cookie: "session=#{System.get_env("AOC_SESSION")}" ])
|
||||
create_file(file, resp.body)
|
||||
end
|
||||
end
|
||||
|
||||
defp run_file(day, file \\ nil) do
|
||||
module(day).main(if file, do: read(file), else: IO.read(:stdio, :eof))
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user