Reputation: 15
Good Morning
I have a list in following format:
[(1-4),(2-4), (3-4)]
I'd like to change it to:
[4,3,4,2,4,1]
I have tried 2 programs:
changeList([], Z) :-
write(Z).
changeList([(A-B)|T], Z) :-
append([A], Z, Y),
append([B], Y, X),
changeList(T, X).
and the second one:
changeList([],Z) :-
write(Z).
changeList([(X-Y)|T], Z) :-
W = [X|Z],
C = [Y|W],
changeList(T,C).
Sadly the result is always: [4,3,4,2,4,1|_38]. Where do i make a mistake?
Upvotes: 1
Views: 68
Reputation: 5645
foldl/4 is a friend for you :
changeList(In, Out) :-
foldl(reverse_one, In, [], Out).
reverse_one((X-Y), In, [Y,X|In]).
Example :
?- changeList([(1-4),(2-4),(3-4)],Out).
Out = [4, 3, 4, 2, 4, 1].
Upvotes: 0
Reputation: 2662
You can solve your problem with different metods. If you want to get the list in reverse order, you need a further input variable which is an empty list. Using your code you can write:
changeList([],Z,Z).
changeList([(A-B)|T],Acc,Z) :-
append([A], Acc, Y),
append([B], Y, X),
changeList(T,X,Z).
?- changeList([(1-4),(2-4),(3-4)],[],Z).
Z = [4, 3, 4, 2, 4, 1]
You can avoid the use of append/3
in this way:
myReverse([],Z,Z).
myReverse([(A-B)|T],Acc,Z):-
myReverse(T,[B,A|Acc],Z).
?- myReverse([(1-4),(2-4),(3-4)],[],Z).
Z = [4, 3, 4, 2, 4, 1]
You have another solution which is to print the list in an ordered way, then reverse it using built-in predicate (in SWI) reverse/2
:
changeListOrd([],[]).
changeListOrd([(A-B)|T], [A,B|TL]):-
changeListOrd(T,TL).
change(L,Lout):-
changeListOrd(L,L1),
reverse(L1,Lout).
?- change([(1-4),(2-4),(3-4)],Z).
Z = [4, 3, 4, 2, 4, 1]
I suggest you to go with the second solution (myReverse/3
) so you don't need both append/3
and reverse/2
.
Upvotes: 1