List Manipulation in prolog - list

Given a list such that [[%,A,B,C,%D,E,%],[%,F,G,%,H,I,J,%]] how do I return [[A,B,C],[D,E],[F,G],[H,I,J]]
I tried the following code:
filtertolists([],[]).
filtertolists([Head|Tail],Y):-
(Head = '%' ->
filtertolists(Tail,Y)).
I want to get the first element from the list of lists, and check whether members of the list are equal to '%' and start creating the list to be given as output, but after getting the head how do I check each element in it?

I would split the task into two tasks:
iterating over the list of lists
removing the elements of one list
My resulting sourceocde would look like this:
filtertolists([],[]).
filtertolists([List|Tail], [FilteredList|FilteredTail]):-
filterList(List, FilteredList),
filtertolists(Tail, FilteredTail).
filterList([], []).
% your filter code for one list goes here .
filterList(...).
filterList(...).

Related

I am trying to remove the last item of each list in a list of lists

I have a data structure which is a list of lists. I want to remove the last item of each list, preferably using a filter. How would i go about doing this?
Here is an example show how to do it:
map (\xs->if null xs then xs else init xs) [[], [1..3], [4..6]]
and the result is:
[[],[1,2],[4,5]]
Note that it need to check each list in list whether is empty before remove the last item of the list, since init cannot apply to empty list.

How to write a prolog program that takes List1 and List2 as inputs, and the resulting list is the alternating elements of List1 and List2? [duplicate]

This question already has answers here:
Shuffle in prolog
(2 answers)
Closed 5 years ago.
This is my first attempt at using recursion over lists on a non-sample program so bare with my inexperience!
Expected Valid Queries:
mixElements([],[a,b,c], [a,b,c]).
mixElements([a,b],[],[a,b]).
mixElements([a,b,c],[d,e,f],[a,d,b,e,c,f]).
mixElements([a,b,c],[d,e,f,g,h],[a,d,b,e,c,f,g,h]).
Here I tried to create the base case for when the inputs lists are empty, the Result is simply returned.
/* Base cases */
mixElements([],[],Result).
The logic for my recursive statement is that the input lists must be at least 1 or more elements. Thus they must both be represented by [H|L] respectively for list 1 and 2. Then it will append H1 and H2 to Result to create the alternating pattern of list elements. Finally it will call mixElements with the remainder of the lists, L1 and L2, and the Result list that should now contain the first head elements of both lists.
/* Recursive case where both L1 and L2 are not empty */
mixElements([H1|L1],[H2|L2],Result) :- append(H1,H2,Result), mixElements(L1,L2,Result).
My resulting output is always "no".
When dealing with lists it's usually worthwhile considering DCGs since they yield easily readable code. It further aids readability to choose a descriptive name for the relation, say list_list_interlocked/3. Consider the following code:
list_list_interlocked(L1,L2,I) :-
phrase(interlocked(L1,L2),I).
interlocked([],[]) --> % if both input lists are empty
[]. % the resulting list is also empty
interlocked([],[H2|T2]) --> % if the first input list is empty
[H2], % the head of the second is in the list
interlocked([],T2). % the relation holds for the tail as well
interlocked([H1|T1],[]) --> % if the second input list is empty
[H1], % the head of the first is in the list
interlocked(T1,[]). % the relation holds for the tail as well
interlocked([H1|T1],[H2|T2]) --> % if both lists are non-empty
[H1,H2], % the heads are in the list
interlocked(T1,T2). % the relation holds for the tails as well
Your example queries yield the desired result:
?- list_list_interlocked([],[a,b,c],I).
I = [a,b,c]
?- list_list_interlocked([a,b],[],I).
I = [a,b]
?- list_list_interlocked([a,b,c],[d,e,f],I).
I = [a,d,b,e,c,f]
?- list_list_interlocked([a,b,c],[d,e,f,g,h],I).
I = [a,d,b,e,c,f,g,h]
Basically there are four cases here:
the first list is empty, the second list is empty, in that case the result should be empty:
mixElements([],[],[]).
the first list is empty, the second list is non-empty, in that case, the result is the second list:
mixElements([],[H2|T2],[H2|T2]).
the first list is non-empty, the second list is empty, in that case, the result is the first list:
mixElements([H1|T1],[],[H1|T1]).
finall both lists are non-empty, in that case the two first elements of the result are the heads of the list, followed by mixing the tails of the lists:
mixElements([H1|T1],[H2|T2],[H1,H2|TT]) :-
mixElements(T1,T2,TT).
Now we can put that all together into:
mixElements([],[],[]).
mixElements([],[H2|T2],[H2|T2]).
mixElements([H1|T1],[],[H1|T1]).
mixElements([H1|T1],[H2|T2],[H1,H2|TT]) :-
mixElements(T1,T2,TT).
Now we have created some redundant statements. For instance we can merge the first two statements into one, like:
mixElements([],L,L).
mixElements([H1|T1],[],[H1|T1]).
mixElements([H1|T1],[H2|T2],[H1,H2|TT]) :-
mixElements(T1,T2,TT).
I leave it as an exercise to further improve the predicate. You can for instance use cuts, but this can eliminate the multi-direction of the predicate, which is sometimes very useful.
You're using append/3 where it's not needed. When the pattern is formed by 2 lists of at least one element, you can get the result immediately, then recurse to handle the tails:
mixElements([H1|L1],[H2|L2],[H1,H2|Rest]) :-
!, mixElements(L1,L2,Rest).
mixElements(L1,L2,Rest) :- append(L1,L2,Rest).

How to combine two lists together that are being formed while iterating another list?

I'm using scrapy to iteratively scrape some data, and the data is being output as two lists through each iteration. I want to combine the two lists into one list at each iteration, so that in the end I will have one big list with many sublists(each sublist being the combination of the two lists created from each iteration)
That may be confusing so I will show my current output and code:
using Scrapy I"m iterating in the following way,
for i in response.css(''tr.insider....."):
i.css(a.tab-link:text).extract() #creating the first list
i.css('td::text').extract() #creating the second list
So the current output is something like this
[A,B,C] #first iteration
[1,2,3]
[D,E,F] #second iteration
[4,5,6]
[G,H,I] #third iteration
[7,8,9]
Desired output is
[[A,B,C,1,2,3], [D,E,F,4,5,6],[G,H,I,7,8,9]]
I tried the following code but I'm getting a list of None.
x =[]
for i in response.css(''tr.insider....."):
x.append(i.css(a.tablink::text).extract().extend(i.css('td::text').extract()))
But the return is just
None
None
None
None
None.....
Thanks!
extend function returns None, so you always append None to x.
For your purpose, I this is what you want:
for i in response.css(''tr.insider....."):
i.css('a.tab-link:text, td::text').extract()
You can simply add two lists together and append them to your results list.
results = []
for i in response.css("tr.insider....."):
first = i.css(a.tab-link:text).extract()
second = i.css('td::text').extract()
# combine both and append to results
results.append(first + second)
print(results)
# e.g.: [[A,B,C,1,2,3], [D,E,F,4,5,6],[G,H,I,7,8,9]]

Return all elements followed by an equal element using list comprehensions

So I'm new to Erlang and still on the learning curve, one question asked was to return all elements in a list followed by an equal element, to which I could to.
For example...
in_pair_lc([a,a,a,2,b,a,r,r,2,2,b,a]) -> [a,a,r,2]
I was then asked to do the same using a list comprehension, and I hit my mental block.
My unsuccessful attempt was this:
in_pair_lc([]) -> [];
in_pair_lc([H|T]) ->
[X || X ,_ [H|T], X=lists:nth(X+1, [H|T]).
Although with no look ahead in list comp it doesn't work.
Thanks for any help in advance.
One way to do this with a list comprehension is to create two lists from the input list:
one containing all elements except the very first element
one containing all elements except the very last element
By zipping these two lists together, we get a list of tuples where each tuple consists of adjacent elements from the input list. We can then use a list comprehension to take only those tuples whose elements match:
in_pair_lc([_|T]=L) ->
[_|T2] = lists:reverse(L),
[H || {H,H} <- lists:zip(lists:reverse(T2),T)].
EDIT: based on the discussion in the comments, with Erlang/OTP version 17.0 or newer, the two list reversals can be replaced with lists:droplast/1:
in_pair_lc([_|T]=L) ->
[H || {H,H} <- lists:zip(lists:droplast(L), T)].
The first example will work on both older and newer versions of Erlang/OTP.
I'm not convinced the problem is really about list comprehensions. The core of the problem is zipping lists and then using a trivial "filter" expression in the list comprehension.
If you want to stick to basic, long existing, erlang list functions (sublist, nthtail) you could go with the following:
X = [a,a,a,2,b,a,r,r,2,2,b,a].
[A || {A,A} <- lists:zip(lists:sublist(X, length(X)-1), lists:nthtail(1, X))].

Prolog Insert list as element into another List

In my program my P = [0,1,2] I want to store it into another LIST, because P will keep changing in a loop so I want to store P into a LIST, so my LIST will be like below :
eg.
LIST = [[0,1,2],[3,4,5],[6,7,8]]
create_list([],[]).
create_list(G, [H|G]).
This is what I did, create_list(P,LIST). I not sure how to do it as it keep return me no. But I am pretty sure I can get different P because I am able to print them out each time P changed.
You need to create a predicate that receives the item (list in this case) you want to append to another input list, and this would give you a new list with the which has all the items of your input list plus the new item.
So, it would be something like:
create_list(Item, List, [Item|List]).
Initially the input List would be an empty list ([]), so you might call it
create_list([0,1,2], [], List1),
create_list([3,4,5], List1, List2),
create_list([6,7,8], List2, List).
This will result in List instantiated with [[0,1,2],[3,4,5],[6,7,8]]