2016-04-07 13 views
5

Tôi đang cố gắng tìm ra cách để tạo một vị từ trong prolog tổng các bình phương chỉ là số chẵn trong một danh sách đã cho.Tạo một vị từ trong Prolog tổng các bình phương chỉ các số chẵn trong một danh sách

mong đợi đầu ra:

?- sumsq_even([1,3,5,2,-4,6,8,-7], Sum). 

Sum = 120 ; 

false. 

Những gì tôi biết làm thế nào để làm là để loại bỏ tất cả các số lẻ từ một danh sách:

sumsq_even([], []). 
sumsq_even([Head | Tail], Sum) :- 
    not(0 is Head mod 2), 
    !, 
    sumsq_even(Tail, Sum). 
sumsq_even([Head | Tail], [Head | Sum]) :- 
    sumsq_even(Tail, Sum). 

nào mang lại cho tôi:

Sum = [2, -4, 6, 8] 

Và Tôi cũng biết cách tổng hợp tất cả các ô vuông của các số trong một danh sách:

sumsq_even([], 0) 
sumsq_even([Head | Tail], Sum) :- 
    sumsq_even(Tail, Tail_Sum), 
    Sum is Head * Head + Tail_Sum. 

Nhưng tôi dường như không thể tìm ra cách kết nối hai thứ này lại với nhau. Tôi nghĩ rằng tôi có thể đã đi sai đường về nó nhưng tôi không chắc chắn làm thế nào để xác định các mối quan hệ thích hợp để làm cho nó có ý nghĩa.

Cảm ơn!

+0

Lý tưởng nhất là các chương trình Prolog của bạn là quan hệ * thuần túy *. Điều này có nghĩa là chúng có thể sử dụng được theo mọi hướng, ví dụ như trong trường hợp chung nhất. Ví dụ, chúng tôi cũng muốn có được câu trả lời cho '? - sumsq_even (Ls, Sum) .'. Kiểm tra các câu trả lời được cung cấp bởi @repeat và @tas cho tính tổng quát này. – mat

Trả lời

2

Tách vấn đề của bạn thành các phần nhỏ hơn. Như bạn đã nói, bạn có hai chức năng khác nhau mà nên được kết hợp:

  • loại bỏ số lẻ từ một danh sách (even)
  • tổng tất cả các ô vuông của các số trong một danh sách (sumsq)

vì vậy, ở nơi đầu tiên, sử dụng tên vị khác nhau cho các chức năng khác nhau:

even([], []). 
even([Head | Tail], Sum) :- 
    not(0 is Head mod 2), 
    !, 
    even(Tail, Sum). 
even([Head | Tail], [Head | Sum]) :- 
    even(Tail, Sum). 

sumsq([], 0). 
sumsq([Head | Tail], Sum) :- 
    sumsq(Tail, Tail_Sum), 
    Sum is Head * Head + Tail_Sum. 

trong một vị thứ ba, bạn c một hiện kết hợp hai bước nhỏ sau:

sumsq_even(List, Sum) :- 
    even(List, Even_List), 
    sumsq(Even_List, Sum). 

Trong quy định này, đầu tiên (đầu vào) danh sách được giảm xuống thậm chí yếu tố (Even_List) và sau đó tổng của các ô vuông được tính toán.

Đây là kết quả ví dụ của bạn:

sumsq_even([1,3,5,2,-4,6,8,-7], Sum). 
S = 120. 
2

Bạn thực sự có thể làm cả hai nhiệm vụ (lọc các số chẵn và tổng hợp chúng lên) cùng một lúc:

:- use_module(library(clpfd)). 

nums_evensumsq([],0). 
nums_evensumsq([X|Xs],S0) :- 
    X mod 2 #= 0, 
    nums_evensumsq(Xs,S1), 
    S0 #= S1 + X * X. 
nums_evensumsq([X|Xs],S) :- 
    X mod 2 #= 1, 
    nums_evensumsq(Xs,S). 

Truy vấn vị cung cấp cho các kết quả mong muốn:

?- nums_evensumsq([1,3,5,2,-4,6,8,-7],S). 
S = 120 ? ; 
no 

Bạn có thể viết ngắn hơn nếu sử dụng if_/3 như được định nghĩa here:

nums_evensumsq([],0). 
nums_evensumsq([X|Xs],S0) :- 
    nums_evensumsq(Xs,S1), 
    Y #= X mod 2, 
    if_(Y = 0, S0 #= S1 + X * X, S0 #= S1). 

Lưu ý rằng việc so sánh trong số đầu tiên của if_/3 được thực hiện với =/3 theo quy định here.

+1

Wow! Nó hoạt động theo mọi hướng! – mat

+1

Một chi tiết thực sự là một chút off ... Điều gì về tổng hợp ** hình vuông **? – repeat

+1

@repeat: Làm thế nào đáng xấu hổ. Nó ở ngay trước mắt tôi. Cảm ơn gợi ý, tôi đã sửa mã của mình. – tas

0

Khi bạn nắm vững các khái niệm cơ bản, bạn có thể quan tâm để tìm hiểu về nội dung dựng sẵn.Thư viện aggregate, cung cấp một cách đơn giản để xử lý danh sách, sử dụng viên/2 như các yếu tố danh sách 'accessor':

sumsq_even(Ints, Sum) :- 
    aggregate(sum(C), I^(member(I, Ints), (I mod 2 =:= 0 -> C is I*I ; C = 0)), Sum). 
+1

Không cần sử dụng if-then-else tại đây. 'C = 0' không đóng góp gì vào tổng! – repeat

2

Sử dụng và Prolog viết:

 
:- use_module(library(clpfd)). 
:- use_module(library(lambda)). 

zs_sumevensq(Zs, S) :- 
 maplist (\Z^X^(X  #= Z*Z*(1-(Z mod 2))), Zs, Es), 
 sum (Es, #=, S). 

truy vấn mẫu như được đưa ra bởi các OP :

?- zs_sumevensq([1,3,5,2,-4,6,8,-7], S). 
S = 120. 
Các vấn đề liên quan