2015-09-12 4 views
3

У меня есть список чисел, мне нужно рассчитать сумму четных чисел списка и произведение нечетных чисел того же списка. Я новичок в Prolog, и мои поиски до сих пор не были успешными. Может ли кто-нибудь помочь мне решить эту проблему?Сумма четного, произведения нечетных чисел в Prolog

l_odd_even([]). 
l_odd_even([H|T], Odd, [H|Etail]) :- 
    H rem 2 =:=0, 
    split(T, Odd, Etail). 
l_odd_even([H|T], [H|Otail], Even) :- 
    H rem 2 =:=1, 
    split(T, Otail, Even). 
+0

Можете ли вы показать, что вы уже пробовали ? –

+0

Во-первых, вам нужно сделать попытку. Я понимаю, что вы новичок в Prolog, но что вы узнали до сих пор о Prolog? Поскольку вы имеете дело с * списком чисел *, вы захотите манипулировать списком. Вы можете «обработать список пролога» Google и получить некоторую полезную информацию о том, как управлять списками. Во-первых, '[]' - пустой список, а '[H | T]' - это список с первым элементом 'H' и * rest * списка (* tail *) -' T'. – lurker

+0

ну это мой код до сих пор «l_odd_even ([]). l_odd_even ([H | T], нечетный, [H | Etail]): - ((H rem 2) =: = 0), split (T, Odd, Etail). l_odd_even ([H | T], [H | Otail], Even): - ((H rem 2) =: = 1), split (T, Otail, Even). " Я просто не знаю, как быстро реализовать сумму и продукт после этого –

ответ

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 для подсветки синтаксиса (см. 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

непроверенный!

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). 
+1

Итак, продукт ничего не равен 1? –

+2

@Boris: да, нейтральный элемент умножения. – salva

+1

Я не уверен, но я не думаю, что то, чем вы являетесь, является суммой и произведением чисел в четных и нечетных _позициях_, но кажется, что ОП пытается получить сумму и произведение четных и нечетных _numbers_. –

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! 
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. 

В качестве альтернативы, мы можем определить sumprod_/3 еще более сжато, используя if_/3 и zeven_t/3:

sumprod_(Z,S0-P0,S-P) :- 
    if_(zeven_t(Z), (S0+Z #= S, P0=P), 
        (P0*Z #= P, S0=S)). 
Смежные вопросы