1

私はこのような問題を抱えています:リスト内のすべての要素を見つけて、それ以外のすべての要素が奇数になるようにします。

例えば

?- find([20,1,2,3,4,5,6,7,8,10], L).
L = [20, 2, 4, 6]

通常、他の言語ではリストを調べて条件を確認しますが、このシナリオでPrologで「考える」方法がわかりません。これにどのようにアプローチすればよいですか?

4

2 に答える 2

3

ヘッド要素のペアを考慮してリストにアクセスしてください。

find([A,B|R], [A|T]) :-
   is_odd(B),
   ... etc etc

明らかに、基本再帰ケースとAを破棄する必要があるケースを追加する必要があります。

于 2013-02-07T21:24:41.750 に答える
1

編集:CapelliCsの提案に基づくより良い解決策(これは以下のisodd述語を使用します):

% if N0 and N2 are odd, cut, add N1 to the result and recurse
ff([N0,N1,N2|T], [N1|R]) :- isodd(N0), isodd(N2), !, ff([N1,N2|T], R).
% for any other case where the list has at least three members, cut and recurse
ff([_,N1,N2|T], R) :- !, ff([N1,N2|T], R).
% this is reached if the list has less that three members - we're done
ff(_, []).

% append and prepend '1' to the list to deal with the edges, call ff.
find(L, R) :- append(L, [1], L1), ff([1|L], R).

追加の引数で前の2つの値を追跡する私の古いソリューション:

% isodd(+N)
% helper predicate that succeds for odd numbers.
isodd(N) :- mod(N, 2) =:= 1.

% find(+I, +N1, +N2, +R, -L)
% find/5 is the predicate doing the actual work.
% I is the input list, N1 and N2 are the numbers before the current one,
% R is the intermediate result list and L the result.

% we're done if the input list is empty
find([], _, _, R, R) :- !.

% check if N0 and N2 are odd to see if N1 should be appended to the list.
% if yes, do a cut, append N1 to the result and recurse.
find([N0|T], N1, N2, R, L) :-
   isodd(N0), isodd(N2), !, 
   append(R, [N1], R1), find(T, N0, N1, R1, L).

% if N0 and N2 are not odd (and thus the cut in the previous clause isn't
% reached) just continue the recursion.
find([N0|T], N1, _, R, L) :- find(T, N0, N1, R, L).

% find(+I, -L)
% this predicate is the entry point - initialize the result list and the first
% values for N1 and N2, and append 1 to the input list so we don't need an extra
% predicate for dealing with the last item.
find(I, L) :- append(I, [1], I1), find(I1, 1, 0, [], L).
于 2013-02-07T19:16:18.387 に答える