2022-12-01 04:46:26 -05:00
|
|
|
:- module day1.
|
|
|
|
:- interface.
|
|
|
|
:- import_module basics.
|
|
|
|
:- import_module io.
|
|
|
|
:- import_module list.
|
|
|
|
|
|
|
|
:- pred run(part::in, list(string)::in, io::di, io::uo) is det.
|
|
|
|
|
|
|
|
:- implementation.
|
|
|
|
:- import_module std_util.
|
2022-12-01 13:23:53 -05:00
|
|
|
:- import_module maybe.
|
2022-12-01 04:46:26 -05:00
|
|
|
:- import_module string.
|
|
|
|
:- import_module int.
|
|
|
|
|
|
|
|
run(Part, Args, !IO) :-
|
|
|
|
if Args = [File] then (
|
2022-12-01 13:23:53 -05:00
|
|
|
read_lines_need(File, Lines, !IO),
|
2022-12-01 04:46:26 -05:00
|
|
|
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").
|
|
|
|
|
|
|
|
:- func go(list(string)) = list(int).
|
2022-12-01 13:23:53 -05:00
|
|
|
go(Lines) =
|
|
|
|
sort(converse(ordering), map(sum, gather(map(to_int_may, Lines)))).
|
2022-12-01 04:46:26 -05:00
|
|
|
|
2022-12-01 13:23:53 -05:00
|
|
|
:- func gather(list(maybe(T))) = list(list(T)).
|
|
|
|
gather(Xs) = Ys :- gather(Xs, Ys).
|
2022-12-01 04:46:26 -05:00
|
|
|
|
2022-12-01 13:23:53 -05:00
|
|
|
:- 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]).
|
2022-12-01 04:46:26 -05:00
|
|
|
|
2022-12-01 13:23:53 -05:00
|
|
|
:- func sum(list(int)) = int.
|
|
|
|
sum(Xs) = foldl(plus, Xs, 0).
|