One solution, not tail-recursive (meaning it will overflow the stack given a sufficiently long list).
compute_sum_of_list_squaring_multiples_of_five_or_three([] , 0) .
compute_sum_of_list_squaring_multiples_of_five_or_three([X|Xs] , R) :-
compute_sum_of_list_squaring_multiples_of_five_or_three(Xs , T) ,
transform(X,N) ,
R is T + N.
transform(X , X) :- 0 =:= X mod 5 + X mod 3 , ! .
transform(X , N) :- N is X*X .
Transformed into tail-recursion:
compute_sum_of_list_squaring_multiples_of_five_or_three(Xs,R) :-
compute_sum_of_list_squaring_multiples_of_five_or_three(Xs,0,R)
.
compute_sum_of_list_squaring_multiples_of_five_or_three([] , R , R) .
compute_sum_of_list_squaring_multiples_of_five_or_three([X|Xs] , T , R) :-
transform(X,N) ,
T1 is T+N,
compute_sum_of_list_squaring_multiples_of_five_or_three(Xs , T1, R).
transform(X , X) :- 0 =:= X mod 5 + X mod 3 , ! .
transform(X , N) :- N is X*X .
A generic version:
compute_sum_of_list_squaring_certain_multiples(Xs , Ds , R) :-
compute_sum_of_list_squaring_certain_multiples(Xs , Ds , 0 , R)
.
compute_sum_of_list_squaring_certain_multiples([] , _ , R , R) . % when we get to the end of the list, the accumulator has the desired value. Unify it with the result.
compute_sum_of_list_squaring_certain_multiples([X|Xs] , Ds , T , R) :- % otherwise...
transform(X,Ds,N) , % - transform X (squaring X if divisible an item in Ds, leaving it alone otherwise)
T1 is T+N , % - add the transformed value to the accumulator
compute_sum_of_list_squaring_certain_multiples(Xs,Ds,T1,R) % - and recurse down.
. %
transform(X , [] ,X ) . % no target dividends? leave it alone.
transform(X , [D|_] , N) :- % otherwise...
0 =: X mod D , % - if X is divisible by the current dividend,
!, % - cut off the alternatives,
N is X*X % - square X and unify with the result.
. %
transform(X,[_|Ds],N) :- % Finally (X is not divisible by the dividend in question)...
transform(X,Ds,N) % - uust recurse down and keep looking.
. %
你應該能夠調用上述:
compute_sum_of_list_squaring_certain_multiples([1,2,3,4,5,6] , [3,5] , R) .
並獲得
R = 41
'變換/ 2'不踏實。 – repeat