2016-06-12 6 views
-1

Учитывая некоторый список целых чисел, я хочу рассчитать сумму каждого второго элемента в списке с помощью Prolog?Как суммировать каждую вторую цифру в списке - Пролог?

Например:

[1,2,3,4] => [2+4] = 6 
+2

Показать код, чтобы увидеть, что вы уже пробовали до сих пор. –

ответ

1

Я хотел бы использовать библиотеку (aggregate):

sum_every_nth1(L,I,S) :- aggregate(sum(X), P^(nth1(P,L,X), P mod I=:=0), S). 

?- sum_every_nth1([1,2,3,4],2,S). 
S = 6. 

sum_every_nth1/3 основана на «реляционной» поведения nth1/3, которое связывает позицию (P в образце) в списке к элементу. Таким образом, при вызове с P бесплатно, он связывает его с последовательными индексами. Затем цель P mod I=:=0 отфильтровывает индексы, не удовлетворяющие требованию (вызывают сбой соединения - запятая означает И).

редактировать

библиотека (складочном) имеет определенную цель, а именно на поставку недостающих операторов агрегирования доступных в SQL. Для обработки умножения, я бы предложил разделить «выборку» элементы из фактической операции, выполняемой на них:

every_nth1(L,I,Ns) :- findall(X, (nth1(P,L,X),P mod I=:=0), Ns). 

mul_every_nth1(L,I,M) :- 
    every_nth1(L,I,[N0|Ns]), 
    foldl([N,M0,M1]>>(M1 is M0*N),Ns,N0,M). 

every_nth1/3 получить список выбранных элементов, foldl/4 ухаживает умножать их.

?- mul_every_nth1([1,2,3,4],2,M). 
M = 8. 

редактировать

если вы пропустили библиотеку (Yall):

multiply(N,M0,M1) :- M1 is M0*N. 

mul_every_nth1(L,I,M) :- 
    every_nth1(L,I,[N0|Ns]), 
    foldl(multiply,Ns,N0,M). 
+0

(совокупность) обычно загружается автоматически, поэтому ничего не требуется. Во всяком случае, '? - [library (aggregate)].' Будет загружать его. В исходном файле используйте вместо этого:: use_module (library (aggregate)). ' – CapelliC

+0

Спасибо! :) Умм, можете ли вы прокомментировать этот код? – user3153616

+0

Libary aggregate, в реализациях SWI-Prolog ver 7.2 :)) – user3153616

2

Есть несколько способов сделать это, но, чтобы дать вам представление о том, с помощью простого рекурсивного решения, используя аккумулятор для отслеживания текущей суммы:

% Sets accumulator to 0 for convenience 
sum_second(List,Result) :- sum_second(List,0,Result). 

sum_second([],A,A).    % Empty list 
sum_second([_],A,A).   % One element left in list 
sum_second([_,H|T],A,R) :-  % Accumulate sum of second element 
    A2 is A+H, 
    sum_second(T,A2,R). 

Пример использования:

?- sum_second([1],R). 
R = 0. 
?- sum_second([1,2],R). 
R = 2. 
?- sum_second([1,2,3,4,5,6],R). 
R = 12. 
+3

'? - sum_second (Ls, _, _).' Показывает только одно решение. Конечно, мы ожидаем немного больше от отношения? – mat

+3

Почему все разрезы? Они не нужны и их следует избегать, если для них не существует конкретной, преднамеренной потребности.Кроме того, вы можете предоставить более аккуратный, предикат для вызова этого: 'sum_second (Ls, R): - sum_second (Ls, 0, R) .', чтобы вызывающий абонент не должен был указывать начальное значение аккумулятора. – lurker

+1

Какова цель оператора «!»? – user3153616

3

Хотя solution by @SeekAndDestroy хорошо, я хотел бы добавить:

  1. Используйте для декларативной целочисленной арифметики.

     
    :- use_module(library(clpfd)). 
    
  2. Использовать индексацию первого аргумента, чтобы избежать бесполезных точек выбора.

     
    list_evens_odds([], [], []). 
    list_evens_odds([X|Xs], [X|Es], Os) :- 
        list_evens_odds(Xs, Os, Es). 
    

Вот так!

Суммируя весь другой пункт (начиная с 2-го), запрос следующим образом:

 
?- list_evens_odds([1,2,3,4], _, Zs),  sum (Zs, #=, Sum). 
Zs = [2,4], Sum = 6. 
+0

Спасибо :) :))) – user3153616

 Смежные вопросы

  • Нет связанных вопросов^_^