偶数的总和,Prolog中奇数的乘积

时间:2015-09-12 21:21:15

标签: list prolog

我有一个数字列表,我需要计算列表的偶数和相同列表的奇数的乘积。我是Prolog的新手,到目前为止我的搜索都没有成功。任何人都可以帮我解决吗?

mkdir -p /some/directory/you/want/to/exist || exit 1

4 个答案:

答案 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)

使用

:- use_module(library(clpfd)).

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_/3zeven_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!