Prolog:谓词组合列表中具有相同值的元素
Prolog: Predicate that combines the elements in a list with same value
给定以下列表:
S = [(1,100), (1,125), (2,175), (3,100), (3,250), (3,350), (5,65)]
我需要编写一个函数来创建一个新列表,使新列表中相应元素的第一个值与第一个列表中元素的值相同,但第二个值将是第一个值相等的第一个列表中第二个值的总和。
对于上面的列表,结果列表应该是这样的:
F = [(1,225), (2,175), (3,700), (5,65)]
go(L) :-
S = [(1,100), (1,125), (2,175), (3,100), (3,250), (3,350), (5,65)],
% Start with the first tuple
S = [(Index, Num)|S0],
sum_tuples(S0, Index, Num, L).
% Finish adding
sum_tuples([], Index, Total, [(Index, Total)]).
sum_tuples([(Index, Num)|Tail], Index, Total, L) :-
!,
% Increment the running total
Total1 is Num + Total,
sum_tuples(Tail, Index, Total1, L).
% Record the final total for the previous index
sum_tuples([(Index, Num)|Tail], PrevIndex, Total, [(PrevIndex, Total)|L]) :-
% Start with the new Index
sum_tuples(Tail, Index, Num, L).
swi-prolog 中的结果:
?- time(go(L)).
% 14 inferences, 0.000 CPU in 0.000 seconds (89% CPU, 261721 Lips)
L = [(1,225),(2,175),(3,700),(5,65)].
Guy Coder 的评论说“如果这是用于 SWI-Prolog,考虑转换成对,然后使用 group_pairs_by_key/3,然后对每个键的值使用 sum_list/2。”。假设我们将 (A,B)
称为一个元组,将 A-B
称为一对,它可能看起来像:
tuple_pair((A,B), A-B).
solve(Tuples, Result):-
maplist(tuple_pair, Tuples, Pairs),
sort(1, @=<, Pairs, SortedPairs),
group_pairs_by_key(SortedPairs, KeysGroups),
findall((K, GSum), (member(K-G, KeysGroups), sum_list(G, GSum)), Result).
然后
?- solve([(1,100), (1,125), (2,175), (3,100), (3,250), (3,350), (5,65)], Answer).
Answer = [(1,225), (2,175), (3,700), (5,65)]
给定以下列表:
S = [(1,100), (1,125), (2,175), (3,100), (3,250), (3,350), (5,65)]
我需要编写一个函数来创建一个新列表,使新列表中相应元素的第一个值与第一个列表中元素的值相同,但第二个值将是第一个值相等的第一个列表中第二个值的总和。
对于上面的列表,结果列表应该是这样的:
F = [(1,225), (2,175), (3,700), (5,65)]
go(L) :-
S = [(1,100), (1,125), (2,175), (3,100), (3,250), (3,350), (5,65)],
% Start with the first tuple
S = [(Index, Num)|S0],
sum_tuples(S0, Index, Num, L).
% Finish adding
sum_tuples([], Index, Total, [(Index, Total)]).
sum_tuples([(Index, Num)|Tail], Index, Total, L) :-
!,
% Increment the running total
Total1 is Num + Total,
sum_tuples(Tail, Index, Total1, L).
% Record the final total for the previous index
sum_tuples([(Index, Num)|Tail], PrevIndex, Total, [(PrevIndex, Total)|L]) :-
% Start with the new Index
sum_tuples(Tail, Index, Num, L).
swi-prolog 中的结果:
?- time(go(L)).
% 14 inferences, 0.000 CPU in 0.000 seconds (89% CPU, 261721 Lips)
L = [(1,225),(2,175),(3,700),(5,65)].
Guy Coder 的评论说“如果这是用于 SWI-Prolog,考虑转换成对,然后使用 group_pairs_by_key/3,然后对每个键的值使用 sum_list/2。”。假设我们将 (A,B)
称为一个元组,将 A-B
称为一对,它可能看起来像:
tuple_pair((A,B), A-B).
solve(Tuples, Result):-
maplist(tuple_pair, Tuples, Pairs),
sort(1, @=<, Pairs, SortedPairs),
group_pairs_by_key(SortedPairs, KeysGroups),
findall((K, GSum), (member(K-G, KeysGroups), sum_list(G, GSum)), Result).
然后
?- solve([(1,100), (1,125), (2,175), (3,100), (3,250), (3,350), (5,65)], Answer).
Answer = [(1,225), (2,175), (3,700), (5,65)]