From 7797aa4002dcb6ffe06bf12d12b50cb4ab24f42c Mon Sep 17 00:00:00 2001 From: rhiannon morris Date: Thu, 1 Dec 2022 19:23:53 +0100 Subject: [PATCH] bloop --- aoc.m | 17 +++++++---------- basics.m | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++-- day1.m | 30 ++++++++++++------------------ die.m | 29 ----------------------------- 4 files changed, 70 insertions(+), 59 deletions(-) delete mode 100644 die.m diff --git a/aoc.m b/aoc.m index 6ea4c16..b419b07 100644 --- a/aoc.m +++ b/aoc.m @@ -6,31 +6,28 @@ :- implementation. :- import_module basics. -:- import_module die. :- import_module string. :- import_module list. :- import_module exception. main(!IO) :- wrap_main(main2, !IO). -:- pred main2(io::di, io::uo) is cc_multi. -:- pragma no_determinism_warning(main2/2). +:- pred main2(io::di, io::uo) is det. main2(!IO) :- command_line_arguments(Args, !IO), - (if (Args = [DayS, PartS | Rest], - to_int(DayS, Day), - part(PartS, Part)) - then + (if Args = [DayS, PartS | Rest], + 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")). -:- type solution == (pred(part, list(string), io, io)). -:- inst solution == (pred(in, in, di, uo) is det). +:- type sol == (pred(part, list(string), io, io)). +:- inst sol == (pred(in, in, di, uo) is det). -:- pred solution(int::in, solution::out(solution)) is semidet. +:- pred solution(int::in, sol::out(sol)) is semidet. :- import_module day1. solution(1, day1.run). diff --git a/basics.m b/basics.m index cb70428..8229ec7 100644 --- a/basics.m +++ b/basics.m @@ -1,13 +1,62 @@ :- module basics. :- interface. - :- type part ---> one; two. :- pred part(string, part). :- mode part(in, out) is semidet. -:- mode part(out, in) is semidet. +:- mode part(out, in) is det. + + +:- import_module io. +:- import_module list. +:- import_module string. + +:- pred die(string::in) is erroneous. +:- pred die(string::in, list(poly_type)::in) is erroneous. + +:- pred need(io.res(T)::in, T::out) is det. +:- 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. + + +:- import_module maybe. + +:- func to_int_may(string) = maybe(int). + :- implementation. part("1", one). part("2", two). + + +:- import_module exception. + +:- type die ---> death(string). + +die(Str) :- throw(death(Str)). +die(Fmt, Args) :- die(format(Fmt, Args)). + +wrap_main(Main, !IO) :- + try [io(!IO)] Main(!IO) + then true + catch death(Err) -> ( + format("%s\n", [s(Err)], !IO), + set_exit_status(1, !IO) + ). + +need(ok(X), X). +need(error(E), _) :- die(error_message(E)). + +read_lines_need(File, Lines, !IO) :- + read_named_file_as_lines(File, Res, !IO), + need(Res, Lines). + + +to_int_may(Str) = Out :- + if to_int(Str, N) then Out = yes(N) else Out = no. diff --git a/day1.m b/day1.m index 45435f2..73321e1 100644 --- a/day1.m +++ b/day1.m @@ -7,15 +7,14 @@ :- pred run(part::in, list(string)::in, io::di, io::uo) is det. :- implementation. -:- import_module die. :- import_module std_util. +:- import_module maybe. :- import_module string. :- import_module int. run(Part, Args, !IO) :- if Args = [File] then ( - read_named_file_as_lines(File, LinesM, !IO), - need(LinesM, Lines), + read_lines_need(File, Lines, !IO), Totals = go(Lines), ( Part = one, format("%d\n", [i(det_head(Totals))], !IO) @@ -26,21 +25,16 @@ run(Part, Args, !IO) :- ) else die("expected one readable file"). :- func go(list(string)) = list(int). -go(Lines) = sort(converse(ordering), map(int_sum, gather(Lines))). +go(Lines) = + sort(converse(ordering), map(sum, gather(map(to_int_may, Lines)))). -:- func gather(list(string)::in) = (list(list(string))::out(non_empty_list)). -gather([]) = [[]]. -gather([X | Xs]) = Groups :- - [Ys | Yss] = gather(Xs), - (if X = "" then Groups = [[], Ys | Yss] - else Groups = [[X | Ys] | Yss]). +:- func gather(list(maybe(T))) = list(list(T)). +gather(Xs) = Ys :- gather(Xs, Ys). + +:- pred gather(list(maybe(T))::in, list(list(T))::out(non_empty_list)) is det. +gather([], [[]]). +gather([no | Xs], [[] | Yss]) :- gather(Xs, Yss). +gather([yes(Y) | Xs], [[Y | Ys] | Yss]) :- gather(Xs, [Ys | Yss]). :- func sum(list(int)) = int. -sum(Xs) = foldl(func(X, Y) = X + Y, Xs, 0). - -:- func int_sum(list(string)) = int. -int_sum(Xs) = sum(map(det_to_int, Xs)). - -:- pred need(io.res(T)::in, T::out) is det. -need(ok(X), X). -need(error(E), _) :- die(error_message(E)). +sum(Xs) = foldl(plus, Xs, 0). diff --git a/die.m b/die.m deleted file mode 100644 index 3149536..0000000 --- a/die.m +++ /dev/null @@ -1,29 +0,0 @@ -:- module die. -:- interface. -:- import_module io. -:- import_module list. -:- import_module string. - -:- pred die(string::in) is erroneous. -:- pred die(string::in, list(poly_type)::in) is erroneous. - -:- type main == (pred(io, io)). -:- inst main == (pred(di, uo) is cc_multi). - -:- pred wrap_main(main::in(main), io::di, io::uo) is cc_multi. - -:- implementation. -:- import_module exception. - -:- type die ---> death(string). - -die(Str) :- throw(death(Str)). -die(Fmt, Args) :- die(format(Fmt, Args)). - -wrap_main(Main, !IO) :- - try [io(!IO)] Main(!IO) - then true - catch death(Err) -> ( - format("%s\n", [s(Err)], !IO), - set_exit_status(1, !IO) - ).