Reputation: 55
For example:
positions (X, L, R):-
.
Where:
I got this, but it doesn´t "return" a list, it just gives me individual results:
pos(X,[X|_],0).
pos(,[],):- !,fail. pos(X,[_|R],Pos):- pos(X,R,Pos1), Pos is Pos1+1.
Upvotes: 2
Views: 96
Reputation:
If you have access to nth0/3
or nth1/3
, it can be used to "find" the positions of an element in a list. For example:
?- List = [0,1,2,3,0,4,5,0], nth0(N, List, 0).
List = [0, 1, 2, 3, 0, 4, 5, 0],
N = 0 ;
N = 4 ;
N = 7.
All you need is to collect all answers in a list. Just use bagof/3
:
?- List = [0,1,2,3,0,4,5,0], bagof(N, nth0(N, List, 0), Ns).
List = [0, 1, 2, 3, 0, 4, 5, 0],
Ns = [0, 4, 7].
You can define it as a predicate like this:
positions(X, L, R) :-
bagof(N, nth0(N, L, X), R).
Unlike the other solutions, you can use this to find the positions of any element in the list upon backtracking:
?- positions(X, [0,1,2,0,2], R).
X = 0,
R = [0, 3] ;
X = 1,
R = [1] ;
X = 2,
R = [2, 4].
If you don't want to use nth0/3
, just go ahead and use your own definition of pos/3
, just make sure it does what it should. See for example the answer to the third of the 99 Prolog problems: it is a straight-forward implementation of nth1/3
. You just have to change the 1 to 0 to get 0-based indices. It is almost identical to what you already had (as shown in your question).
Upvotes: 1
Reputation: 726699
You can modify your code like this:
positions(X, L, R) :- positions(X, L, R, 1).
positions(_, [], [], _).
positions(X, [X|T], [I|R], I) :- plus(I, 1, N), positions(X, T, R, N).
positions(X, [Y|T], R, I) :- X \= Y, plus(I, 1, N), positions(X, T, R, N).
The positions/3
clause is there to add the current index I
to positions/4
rule.
The three clauses of positions/4
are as follows:
X
X \= Y
).Upvotes: 0
Reputation: 66210
I think you need a index and creare R
accumulating the matching indexes.
By example
positionH(_, _, [], []).
positionH(I, X, [Y | Tl], Tr):-
Y \= X,
Ip1 is I+1,
positionH(Ip1, X, Tl, Tr).
positionH(I, X, [X | Tl], [I | Tr]):-
Ip1 is I+1,
positionH(Ip1, X, Tl, Tr).
position(X, L, R):-
positionH(0, X, L, R).
Upvotes: 0