Checking the heads of lists of lists - list

I'm trying to write a function that filters on a list of lists however I can't manage to work out how. My first question of course is how to filter a list of lists
[[2,2,2],[1,2,3],[2,2,3]]
filter (==2)
The second thing I'm trying to work out is how to only filter the Head of each of the lists.
Eg for the above filter, I would expect an output of 2 from the first list, and 2 from the third list.
Any help would be much appreciated.
Cheers.

Maybe filter (==2) $ map (head) [[2,2,2],[1,2,3],[2,2,3]] ? But still the problem is very ambiguously stated.
Output:
[2,2]
EDIT:
As Thomas M. DuBuisson said head returns error when the list is empty according to its definition:
badHead :: a
badHead = errorEmptyList "head"
head [] = badHead
whereas take !_ [] = [].

Related

How to solve "unresolved flex record" in else if statement in SML?

I want to find a list of nodes that currently given nodes directly or indirectly connect to.
For example, I have a list of nodes:
[1,2]
and a list of tuples, and each of the tuples represents a direct edge:
[(1,5),(2,4),(4,6)]
So, the nodes I am looking for are
[1,2,5,4,6]
Because, 1 connects to 5, 2 connects to 4. Then, 4 is connected to 6.
To achieve this, I need two a queues, and a list. Each time a new node is discovered, we append the new node to the queue and the list. Then, we remove the first node of the queue, and go to next node. If a new node is connected to the current node of the queue. Then, we add new node to both the queue and the list.
We keep doing this until the queue is empty and we return the list.
So now, I have an append function which appends a list to another list:
fun append(xs, ys) =
case ys of
[] => xs
| (y::ys') => append(xs # [y], ys')
Then, I have a function called getIndirectNodes, which intends to return the lists of nodes that the given nodes indirectly connected to, but throws "unresolved flex record". List1 and List2 have the same items supposedly. But, List1 serves the queue, and list2 servers as the list to be returned.
fun getIndirectNode(listRoleTuples, list1, list2) =
if list1 = []
then list2
else if hd(list1) = #1(hd(listRoleTuples))
then (
append(list1,#2(hd(listRoleTuples)) :: []);
append(list2,#2(hd(listRoleTuples)) :: []);
getIndirectNode(listRoleTuples,tl(list1),list2)
)
else
getIndirectNode(listRoleTuples,tl(list1),list2)
If I remove the else if statement, it works perfectly fine. But, it's not what I intended to do. The problem is in the else if statement. What can I do to fix it?
SML needs to know exactly what shape a tuple has in order to deconstruct it.
You could specify the type of the parameter - listRoleTuples : (''a * ''a) list - but using pattern matching is a better idea.
(There are many other problems with that code, but that's the answer to your question.)
It seems that one of your classmates had this exact tuple problem in a very related task.
Make sure you browse the StackOverflow Q&A's before you ask the same question again.
As for getting the indirect nodes, this can be solved by fixed-point iteration.
First you get all the direct nodes, and then you get the direct nodes of the direct nodes.
And you do this recursively until no more new nodes occur this way.
fun getDirectNodes (startNode, edges) =
List.map #2 (List.filter (fn (node, _) => node = startNode) edges)
fun toSet xs =
... sort and remove duplicates ...
fun getReachableNodes (startNodes, edges) =
let
fun f startNode = getDirectNodes (startNode, edges)
val startNodes = toSet startNodes
val endNodes = toSet (List.concat (List.map f startNodes))
in
if startNodes = endNodes
then endNodes
else getReachableNodes (startNodes # endNodes, edges)
end
This doesn't exactly find indirect end-nodes; it finds all nodes directly or indirectly reachable by startNodes, and it includes startNodes themselves even if they're not directly or indirectly reachable by themselves.
I've tried to make this exercise easier by using sets as a datatype; it would be even neater with an actual, efficient implementation of a set type, e.g. using a balanced binary search tree. It is easier to see if there are no new nodes by adding elements to a set, since if a set already contains an element, it will be equivalent to itself before and after the addition of the element.
And I've tried to use higher-order functions when this makes sense. For example, given a list of things where I want to do the same thing on each element, List.map produces a list of results. But since that thing I want to do, getDirectNodes (startNode, edges) produces a list, then List.map f produces a list of lists. So List.concat collapses that into a single list.
List.concat (List.map f xs)
is a pretty common thing to do.

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.

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))].

List Manipulation in prolog

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(...).

Haskell - get n number of lists from a list of lists

Hey guys so I'm trying and get the n number of lists from a list of lists. I was wondering if there is a method in haskell that works similar to the "take" and "drop" method but instead if would work in my situation. For example:
Input = [ [1,2,3,4], [5,6,7,8], [9,1,2,3], [4,5,6,7], [8,9,1,2], [3,4,5,6] ]
I want to be able to take the first 3 elements from this list of lists and end up with something like this:
Output = [ [1,2,3,4], [5,6,7,8], [9,1,2,3]]
I also want to be able to drop the first 3 elements from this list of lists and end up with something like this:
Output = [[4,5,6,7], [8,9,1,2], [3,4,5,6]]
Is it possible to do something like this in haskell.? Can anyone point me into the right direction on how to tackle this problem. Thanks in advance.
take and drop do exactly that. They work the same for all element types, even if the element type is a list type.
Prelude> take 3 [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16],[17,18,19,20]]
[[1,2,3,4],[5,6,7,8],[9,10,11,12]]
Prelude> drop 3 [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16],[17,18,19,20]]
[[13,14,15,16],[17,18,19,20]]