Merge and aggregate datasets: Difference between revisions

Add Mercury task
(Add Mercury task)
Line 671:
3003 3003 Kemeny Thu 12 Nov 2020 \[LongDash] \[LongDash]
5005 5005 Kurtz \[LongDash] \[LongDash] \[LongDash]</pre>
=={{header|Mercury}}==
<lang Prolog>:- module rosetta.
 
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
 
:- implementation.
:- import_module list, int, float, string, maybe, solutions.
 
:- pred patient(int::out, string::out) is multi.
patient(1001, "Hopper").
patient(4004, "Wirth").
patient(3003, "Kemeny").
patient(2002, "Gosling").
patient(5005, "Kurtz").
 
:- func nan = float.
nan = det_to_float("NaN").
 
:- type maybe_date ---> date(year::int, month::int, day::int); no.
 
:- pred visit(int::out, maybe_date::out, float::out) is multi.
visit(2002, date(2020,09,10), 6.8).
visit(1001, date(2020,09,17), 5.5).
visit(4004, date(2020,09,24), 8.4).
visit(2002, date(2020,10,08), nan).
visit(1001, no, 6.6).
visit(3003, date(2020,11,12), nan).
visit(4004, date(2020,11,05), 7.0).
visit(1001, date(2020,11,19), 5.3).
 
%% Utilities
:- pred bag_count(pred(T)::(pred(out) is nondet), int::out) is det.
:- pred bag_sum(pred(float)::(pred(out) is nondet), float::out) is det.
:- pred bag_avg(pred(float)::(pred(out) is nondet), float::out) is det.
bag_count(Predicate, Count) :-
promise_equivalent_solutions[Count] (
unsorted_aggregate(Predicate,
(pred(_X::in,Y::in,Z::out) is det :- Z is Y+1),
0, Count)).
bag_sum(Predicate, Sum) :-
promise_equivalent_solutions[Sum] (
unsorted_aggregate(Predicate,
(pred(X::in,Y::in,Z::out) is det :- Z is X+Y),
0.0, Sum)).
bag_avg(Predicate, Avg) :-
bag_count(Predicate, N),
bag_sum(Predicate, Sum),
(if N = 0 then Avg = nan else Avg is Sum/float(N)).
 
:- pred max_date(maybe_date::in, maybe_date::in, maybe_date::out) is det.
:- pred bag_max_date(pred(maybe_date)::(pred(out) is nondet), maybe_date::out) is det.
max_date(date(Y1,M1,D1), date(Y2,M2,D2), Date) :-
compare(R, date(Y1,M1,D1), date(Y2,M2,D2)),
(if R = (>) then Date = date(Y1,M1,D1) else Date = date(Y2,M2,D2)).
max_date(no, date(Y,M,D), date(Y,M,D)).
max_date(date(Y,M,D), no, date(Y,M,D)).
max_date(no, no, no).
bag_max_date(Predicate, Max) :-
promise_equivalent_solutions[Max]
(unsorted_aggregate(Predicate, max_date, no, Max)).
 
main(!IO) :-
io.write_string("{Id, Lastname, SumScores, AvgScores, MaxDate}:\n", !IO),
solutions((pred({Id,Lastname,Sum,Avg,MaxDate}::out) is nondet :-
patient(Id,Lastname),
Scores = (pred(Score::out) is nondet :- visit(Id,_,Score), \+is_nan(Score)),
bag_avg(Scores, Avg),
bag_sum(Scores, Sum),
Dates = (pred(Date::out) is nondet :- visit(Id,Date,_)),
bag_max_date(Dates, MaxDate)),
Solutions),
foldl(io.write_line, Solutions, !IO).</lang>
{{out}}
<pre>{Id, Lastname, SumScores, AvgScores, MaxDate}:
{1001, "Hopper", 17.4, 5.8, date(2020, 11, 19)}
{2002, "Gosling", 6.8, 6.8, date(2020, 10, 8)}
{3003, "Kemeny", 0.0, nan, date(2020, 11, 12)}
{4004, "Wirth", 15.4, 7.7, date(2020, 11, 5)}
{5005, "Kurtz", 0.0, nan, no}</pre>
 
=={{header|Nim}}==
136

edits