sort_employee_average_salary/2
Primind o listă identică celei de la Exercițiul 2, în lista de rezultat ordonați angajații după salariul mediu câștigat, în ordine descrescătoare.
?- sort_employee_average_salary([employee_salary(peter, 1000), employee_salary(oliver, 1200),
employee_salary(sam, 700), employee_salary(oliver, 800),
employee_salary(sam, 900), employee_salary(sandra, 4500),
employee_salary(peter, 1200), employee_salary(oliver, 400)], Result).
Result = [(sandra, 4500), (peter, 1100), (oliver, 800), (sam, 800)]
Hint: folosește
predsort/3cu un comparator custom care compară salariile în ordine inversă. Vezi Predicate predefinite pe liste.
Te-ai blocat?
editor
soluție
sum_and_count_by_name(_, [], 0, 0) :- !.
sum_and_count_by_name(Name, [employee_salary(Name, CurrentSalary) | Tail], Sum, Count) :-
sum_and_count_by_name(Name, Tail, SumTail, CountTail),
Sum is SumTail + CurrentSalary,
Count is CountTail + 1, !.
sum_and_count_by_name(Name, [_ | Tail], Sum, Count) :-
sum_and_count_by_name(Name, Tail, Sum, Count).
remove_by_name(_, [], []).
remove_by_name(Name, [employee_salary(Name, _) | Tail], TR) :-
remove_by_name(Name, Tail, TR), !.
remove_by_name(Name, [H | T], [H | TR]) :-
remove_by_name(Name, T, TR).
employee_average_salary([], []) :- !.
employee_average_salary([employee_salary(Name, Salary) | Tail], [(Name, Average) | TR]) :-
sum_and_count_by_name(Name, [employee_salary(Name, Salary) | Tail], Sum, Count),
Average is Sum / Count,
remove_by_name(Name, [employee_salary(Name, Salary) | Tail], NewList),
employee_average_salary(NewList, TR).
% comparator descrescător — inversăm argumentele compare
my_cmp(X, (_, Salary1), (_, Salary2)) :-
compare(X, Salary2, Salary1).
sort_employee_average_salary(InputList, SortedList) :-
employee_average_salary(InputList, TempList),
predsort(my_cmp, TempList, SortedList).
?-
Tastează o interogare (ex. father_of(sandra, X).) și apasă Enter — sau apasă pe un caz de test de mai jos.
Cazuri de test (1 — apasă pe unul ca să îl rulezi, sau Verifică pentru toate)
?
sort_employee_average_salary([employee_salary(peter,1000), employee_salary(oliver,1200), employee_salary(sam,700), employee_salary(oliver,800), employee_salary(sam,900), employee_salary(sandra,4500), employee_salary(peter,1200), employee_salary(oliver,400)], R).
așteptat: R = [(sandra,4500.0),(peter,1100.0),(oliver,800.0),(sam,800.0)]