Sum of even, product of odd numbers in Prolog

后端 未结 4 2040
悲&欢浪女
悲&欢浪女 2020-12-21 09:33

I have a list of numbers, I need to calculate the sum of the even numbers of the list and the product of the odd numbers of the same list. I\'m new in Prolog, and my searche

相关标签:
4条回答
  • 2020-12-21 09:57

    untested!

    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).
    
    0 讨论(0)
  • 2020-12-21 10:03

    Here is a suggestion for the sum of the even numbers from a list:

    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
    

    Note: My Prolog has oxidized, so there might be better solutions. :-)

    Note: Holy cow! There seems to be no Prolog support for syntax highlighting (see here), so I used Erlang syntax. Ha, it really works. :-)

    Running some queries in GNU Prolog, I get:

    | ?- 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
    

    The ideas applied here should enable you to come up with the needed product.

    0 讨论(0)
  • 2020-12-21 10:04

    It shouldn't get much simpler than

    %
    % 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!
    
    0 讨论(0)
  • 2020-12-21 10:12

    Use clpfd!

    :- use_module(library(clpfd)).
    

    Building on meta-predicate foldl/4, we only need to define what a single folding step is:

    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.
    

    Let's fold sumprod_/3 over the list!

    l_odd_even(Zs,ProductOfOdds,SumOfEvens) :-
       foldl(sumprod_,Zs,0-1,SumOfEvens-ProductOfOdds).
    

    Sample query:

    ?- l_odd_even([1,2,3,4,5,6,7],Odd,Even).
    Odd = 105,
    Even = 12.
    

    Alternatively, we can define sumprod_/3 even more concisely by using if_/3 and zeven_t/3:

    sumprod_(Z,S0-P0,S-P) :-
       if_(zeven_t(Z), (S0+Z #= S, P0=P),
                       (P0*Z #= P, S0=S)).
    
    0 讨论(0)
提交回复
热议问题