So my problem sounds like this: Given a list of integer numbers, generate the list of permutations with the property that the absolute value of the difference between 2 consecutive values from the permutation is <=3
.
For example : L=[2,7,5]
==> [[2,5,7], [7,5,2]]
.
So far I wrote this
domains
list=integer*
lista=list*
predicates
perm(list,list)
permutations(list,lista,integer)
delete(integer,list,list)
diff(list,integer)
clauses
perm([],[]).
perm(Y,[A|X]):-
delete(A,Y,Y1),
perm(Y1,X).
delete(A,[A|X],X).
delete(A,[B|X],[B|Y]):-
delete(A,X,Y).
perm_aux(L,X,3):-
perm(L,X),
diff(X,R),
abs(R)<=3.
diff([],0).
diff(???):-
??????
permutations(L,R,3):-
findall(X,perm_aux(L,X,3),R).
So I'm stuck in the part where I make the difference. I have no idea how to do it for every 2 consecutive elements. Please help me.
I wouldn't have diff
return a difference, but rather give it the max difference you want and have it either fail as soon as it hits a difference that is too big, or it succeeds.
So diff(List, Max).
And calling it, instead of:
diff(X,R),
abs(R)<=3. % Note that this should be =<
You'd have:
diff(X, 3).
Then your base cases are:
diff([], _). % Empty list always succeeds
diff([_], _). % Single element list always succeeds
And your recursive case would look like:
diff([X,Y|T], Max) :-
abs(X-Y) =< Max,
diff([Y|T], Max).
If you would like diff
to provide a maximum absolute difference of consecutive values, you could define it as:
max_diff(X, Max) :-
max_diff(X, 0, Max).
max_diff([], M, M).
max_diff([_], M, M).
max_diff([X,Y|T], MaxSoFar, Max) :-
Diff is abs(X-Y),
( Diff > MaxSoFar
-> max_diff([Y|T], Diff, Max)
; max_diff([Y|T], MaxSoFar, Max)
).