我有一个数字列表,我需要计算列表的偶数和相同列表的奇数的乘积。我是Prolog的新手,到目前为止我的搜索都没有成功。任何人都可以帮我解决吗?
mkdir -p /some/directory/you/want/to/exist || exit 1
答案 0 :(得分:2)
以下是对列表中偶数总和的建议:
even(X) :-
Y is mod(X,2), % using "is" to evaluate to number
Y =:= 0.
odd(X) :- % using even
Y is X + 1,
even(Y).
sum_even(0, []). % empty list has zero sum
sum_even(X, [H|T]) :-
even(H),
sum_even(Y, T),
X is Y+H.
sum_even(X, [H|T]) :-
odd(H),
sum_even(X, T). % ignore the odd numbers
注意:我的Prolog已氧化,因此可能有更好的解决方案。 : - )
注意:圣牛!似乎没有Prolog支持语法高亮(请参阅here),因此我使用了Erlang语法。 哈,它确实有效。 : - )在GNU Prolog中运行一些查询,我得到:
| ?- sum_even(X,[]).
X = 0 ?
yes
| ?- sum_even(X,[2]).
X = 2 ?
yes
| ?- sum_even(X,[3]).
X = 0 ?
yes
| ?- sum_even(X,[5,4,3,2,1,0]).
X = 6 ?
yes
这里应用的想法应该使您能够提出所需的产品。
答案 1 :(得分:2)
使用clpfd!
:- use_module(library(clpfd)).
在meta-predicate foldl/4
的基础上,我们只需要定义单个折叠步骤:
sumprod_(Z,S0,S) :-
M #= Z mod 2,
rem_sumprod_(M,Z,S0,S).
rem_sumprod_(0,Z,S0-P,S-P) :-
S0 + Z #= S.
rem_sumprod_(1,Z,S-P0,S-P) :-
P0 * Z #= P.
让我们在列表上折叠sumprod_/3
!
l_odd_even(Zs,ProductOfOdds,SumOfEvens) :-
foldl(sumprod_,Zs,0-1,SumOfEvens-ProductOfOdds).
示例查询:
?- l_odd_even([1,2,3,4,5,6,7],Odd,Even).
Odd = 105,
Even = 12.
或者,我们可以使用if_/3
和zeven_t/3
更简洁地定义sumprod_/3
:
sumprod_(Z,S0-P0,S-P) :-
if_(zeven_t(Z), (S0+Z #= S, P0=P),
(P0*Z #= P, S0=S)).
答案 2 :(得分:1)
未测试!
sum_odd_product_even([], S, P, S, P).
sum_odd_product_even([H|T], S0, P0, S, P) :-
S1 is S0 + H,
sum_even_product_odd(T, S1, P0, S, P).
sum_even_product_odd([], S, P, S, P).
sum_even_product_odd([H|T], S0, P0, S, P) :-
P1 is P0 * H,
sum_odd_product_even(T, S0, P1, S, P).
sum_odd_product_even(L, S, P) :-
sum_odd_product_even(L, 0, 1, S, P).
sum_even_product_odd(L, S, P) :-
sum_even_product_odd(L, 0, 1, S, P).
答案 3 :(得分:0)
它不应该比
简单得多%
% invoke the worker predicate with the accumulators seeded appropriately.
%
odds_and_evens( [O] , P , S ) :- odds_and_evens( [] , O , 0 , P , S ) .
odds_and_evens( [O,E|Ns] , P , S ) :- odds_and_evens( Ns , O , E , P , S ) .
odds_and_evens( [] , P , S , P , S ) . % if the list is exhausted, we're done.
odds_and_evens( [O] , X , X , P , S ) :- % if it's a single element list, we've only an odd element...
P is X*O , % - compute it's product
. % - and we're done.
odds_and_evens( [O,E|Ns] , X , Y , P , S ) :- % if the list is at least two elements in length'e both an odd and an even:
X1 is X*O , % - increment the odd accumulator
Y1 is Y+E , % - increment the even accumulator
odds_and_evens( Ns , X1 , Y1 , P , S ) % - recurse down (until it coalesces into one of the two special cases)
. % Easy!