47 lines
1.2 KiB
Mathematica
47 lines
1.2 KiB
Mathematica
|
:- 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 die.
|
||
|
:- import_module std_util.
|
||
|
:- 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),
|
||
|
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).
|
||
|
go(Lines) = sort(converse(ordering), map(int_sum, gather(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 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)).
|