From 835eeefc0a38071de02b30e210345918218bca3d Mon Sep 17 00:00:00 2001 From: rhiannon morris Date: Thu, 1 Dec 2022 10:46:26 +0100 Subject: [PATCH] day1 --- .gitignore | 1 + aoc.m | 3 ++- day1.m | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 day1.m diff --git a/.gitignore b/.gitignore index a2a2f6c..c275e8f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ Mercury/ *.mh *.err aoc +input/ diff --git a/aoc.m b/aoc.m index 956b953..6ea4c16 100644 --- a/aoc.m +++ b/aoc.m @@ -31,7 +31,8 @@ main2(!IO) :- :- inst solution == (pred(in, in, di, uo) is det). :- pred solution(int::in, solution::out(solution)) is semidet. -solution(_, _) :- fail. +:- import_module day1. +solution(1, day1.run). :- pred run(int::in, part::in, list(string)::in, io::di, io::uo) is det. diff --git a/day1.m b/day1.m new file mode 100644 index 0000000..45435f2 --- /dev/null +++ b/day1.m @@ -0,0 +1,46 @@ +:- 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)).