diff --git a/aoc.bqn b/aoc.bqn index e33f8eb..e68f9a3 100644 --- a/aoc.bqn +++ b/aoc.bqn @@ -1,6 +1,6 @@ Day1 ⇐ { nums ← •BQN⎊0¨ •FLines 𝕩 - sums ← ∨ (+´ {𝕩↑𝕨↓nums}´)¨ (»⋈¨ ⊢-») / 0⊸≡¨ nums + sums ← ∨ (+´ {𝕩↑𝕨↓nums}´)¨ (»⋈¨ ⊢-») /0=nums ⟨⊑sums, +´ 3↑sums⟩ } •Show Day1 ⊑•args diff --git a/aoc.m b/aoc.m index b419b07..3d84b57 100644 --- a/aoc.m +++ b/aoc.m @@ -9,32 +9,33 @@ :- import_module string. :- import_module list. :- import_module exception. +:- import_module univ. main(!IO) :- wrap_main(main2, !IO). -:- pred main2(io::di, io::uo) is det. +:- pred main2(io::di, io::uo) is cc_multi. main2(!IO) :- command_line_arguments(Args, !IO), - (if Args = [DayS, PartS | Rest], + (if Args = [DayS, PartS, File], to_int(DayS, Day), - part(PartS, Part) then - run(Day, Part, Rest, !IO) - else if Args = [D, P | _] then - die("expected a day and a part, got ""%s"" ""%s""", [s(D), s(P)]) - else - die("expected at least two args")). + part(PartS, Part) then ( + read_lines_need(File, Lines, !IO), + run_day(Day, Part, Lines, Out), + write_line(univ_value(Out), !IO) + ) else + die("expected day, part, filename")). -:- type sol == (pred(part, list(string), io, io)). -:- inst sol == (pred(in, in, di, uo) is det). +:- type sol == (pred(part, list(string), univ)). +:- inst sol == (pred(in, in, out) is cc_multi). :- pred solution(int::in, sol::out(sol)) is semidet. :- import_module day1. solution(1, day1.run). -:- pred run(int::in, part::in, list(string)::in, io::di, io::uo) is det. - -run(Day, Part, Args, !IO) :- +:- pred run_day(int, part, list(string), univ). +:- mode run_day(in, in, in, out) is cc_multi. +run_day(Day, Part, Lines, Out) :- if solution(Day, P) then - P(Part, Args, !IO) + P(Part, Lines, Out) else die("no solution for day %d", [i(Day)]). diff --git a/basics.m b/basics.m index 8229ec7..236595e 100644 --- a/basics.m +++ b/basics.m @@ -1,7 +1,7 @@ :- module basics. :- interface. -:- type part ---> one; two. +:- type part ---> one; two. :- pred part(string, part). :- mode part(in, out) is semidet. :- mode part(out, in) is det. @@ -18,10 +18,9 @@ :- pred read_lines_need(string::in, list(string)::out, io::di, io::uo) is det. -:- type main == (pred(io, io)). -:- inst main == (pred(di, uo) is det). - -:- pred wrap_main(main::in(main), io::di, io::uo) is cc_multi. +:- pred wrap_main(pred(io, io), io, io). +:- mode wrap_main(pred(di, uo) is cc_multi, di, uo) is cc_multi. +:- mode wrap_main(pred(di, uo) is det, di, uo) is cc_multi. :- import_module maybe. diff --git a/day1.m b/day1.m index 73321e1..df3589d 100644 --- a/day1.m +++ b/day1.m @@ -1,10 +1,10 @@ :- module day1. :- interface. :- import_module basics. -:- import_module io. :- import_module list. +:- import_module univ. -:- pred run(part::in, list(string)::in, io::di, io::uo) is det. +:- pred run(part::in, list(string)::in, univ::out) is cc_multi. :- implementation. :- import_module std_util. @@ -12,17 +12,9 @@ :- import_module string. :- import_module int. -run(Part, Args, !IO) :- - if Args = [File] then ( - read_lines_need(File, Lines, !IO), - Totals = go(Lines), - ( Part = one, - format("%d\n", [i(det_head(Totals))], !IO) - ; Part = two, - Res = sum(take_upto(3, Totals)), - format("%d\n", [i(Res)], !IO) - ) - ) else die("expected one readable file"). +:- pragma no_determinism_warning(run/3). +run(one, Lines, univ(det_head(go(Lines)))). +run(two, Lines, univ(sum(take_upto(3, go(Lines))))). :- func go(list(string)) = list(int). go(Lines) =