ocaml remove duplicates in a list - list

Hey guys I am having a bit of trouble i have a general idea what the code should be but not to sure what to do from here.
The question is: Define a function remove_elts taking a list of items as well as a list of items to
remove from the first list, and returning a list with all occurrences of the items
to be removed gone.
My code is :
let remove_elts l reml =
match l with
[] -> false
| hd :: tl -> if hd = l then reml
else hd :: remove_elts l tl;;

Any filtering function, i.e., a function that takes a container and returns another container that contains elements of the input container that satisfy some property, is implemented using the following algorithm:
output-sequence = []
foreach element in the input-sequeunce:
if element satisfies condition:
output-sequence := output-sequence + element
This iteration has two elements which differ with each step, the element variable that takes in order the elements of the input-sequence and the output-sequence that grows every time, the <element> satisfies the condition.
In functional programming, iteration is commonly represented with recursion which is more natural from the mathematical point of view. Anything that changes in the iteration will become a parameter of the recursive function, and each step is represented as a recursive call with the new values of the variables. So the same iteration in the functional style (pseudocode)
filter input-sequence output-sequence =
if is-empty input-sequence then output-sequence
else
let element = first-element-of input-sequence in
let rest = drop-first-element input-sequence in
if element satisfies condition
then filter rest (output-sequence + element)
else filter rest output-sequence
And the iteration is called as
filter input-sequence []
So it is a little bit more verbose then the foreach but this is because foreach is basically a syntactic sugar.
Now, your task is to implement this in OCaml, keeping in mind two things:
1) In OCaml you can use pattern matching, instead of is-empty,first-element-of, and drop-first-element primitives.
2) You're using a singly-linked list as the sequence, so appending an element to the end of it is very expensive, it is O(N) (as you have to go through all elements, until you reach the end), and doing this in cycle will make your algorithm O(N^2), so instead you should prepend to the beginning (which is O(1)) and at the end of recursion, reverse the list.

Related

SML counting within a pair of lists

I am trying to write a function in SML that takes in a pair of lists. The first list in the pair is a list of integers and the second list is a list of booleans. Ex: (([3, 5, 9], [true, false, false])). I am having trouble with the proper syntax to return how many times 'true' is found in the second list.
You would want to break this down.
Can you count the number of times a value is found in a list?
Can you pattern match out the second list in the tuple?
The first one can be accomplished by implementing a count function. A basic shell for that would look something like:
fun count (_, []) = ...
| count (v, (x::xs)) =
if ... then ...
else ...
For the second, well, you can see pattern-matching for binding names to the elements of a tuple in the above code.
Doing anything more would be doing your homework for you, and that would be a disservice.

Scala List of tuple becomes empty after for loop

I have a Scala list of tuples, "params", which are of size 28. I want to loop through and print each element of the list, however, nothing is printed out. After finishing the for loop, I checked the size of the list, which now becomes 0.
I am new to scala and I could not figure this out after a long time googling.
val primes = List(11, 13, 17, 19, 2, 3, 5, 7)
val params = primes.combinations(2)
println(params.size)
for (param <- params) {
print(param(0), param(1))
}
println(params.size)
combinations methods in List create an Iterator. Once the Iterator is consumed using methods like size, it will be empty.
From the docs
one should never use an iterator after calling a method on it.
If you comment out println(params.size), you can see that for loop is printing out the elements, but the last println(params.size) will remain as 0.
Complementing Johny's great answer:
Do you know how I can save the result from combination methods to use for later?
Well, as already suggested you can just toList
However, note there is a reason why combinations returns an Iterator and it is because the data can be too big, if you are okay with that then go ahead; but you may still take advantage of laziness.
For example, let's convert the inner lists into a tuples before collecting the results:
val params =
primes
.combinations(2)
.collect {
case a :: b :: Nil => (a, b)
}.toList
In the same way, you may add extra steps in the chain like another map or a filter before doing the toList
Even better, if your end action is something like foreach(foo) then you do not even need to collect everything into a List
primes.combinations(2) returns Iterator.
Iterators are data structures that allow to iterate over a sequence of
elements. They have a hasNext method for checking if there is a next
element available, and a next method which returns the next element
and discards it from the iterator.
So, it is like pointer to Iterable collection. Once you have done iteration you no longer will be able to iterate again.
When println(params.size) executed that time iteration completed while computing size and now params is pointing to end. Because of this for (param <- params) will be equivalent looping around empty collection.
There can 2 possible solution:
Don't check the size before for loop.
Convert iterator to Iterable e.g. list.
params = primes.combinations(2).toList
To learn more about Iterator and Iterable refer What is the relation between Iterable and Iterator?

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.

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

Erlang Iterating through list removing one element

I have the following erlang code:
lists:all(fun(Element) -> somefunction(TestCase -- [Element]) end, TestCase).
Where TestCase is an array. I'm trying to iterate over the list/array with one element missing.
The problem is this code takes O(N^2) time worst case because of the copies of the TestCase array everytime -- is called. There is a clear O(N) Solution in a non functional language.
saved = TestCase[0]
temp = 0
NewTestCase = TestCase[1:]
for a in range(length(NewTestCase)):
somefunction(NewTestCase)
temp = NewTestCase[a]
NewTestCase[a] = saved
saved = temp
... or something like that.
Is there an O(N) solution in erlang?
Of course there is, but it's a little bit more complicated. I am assuming that some_function/1 is indeed a boolean function and you want to test whether it returns true for every sub-list.
test_on_all_but_one([], _Acc) -> true;
test_on_all_but_one([E|Rest], Acc) ->
case somefunction(lists:reverse(Acc,Rest)) of
true -> test_on_all_but_one(Rest, [E|Acc]);
false -> false
end.
This implementation is still O(length(List)^2) as the lists:reverse/2 call will still need O(length(Acc)). If you can modify somefunction/1 to do it's calculation on a list split into two parts, then you can modify the previous call to somefunction(lists:reverse(Acc,Rest)) with somefunction(Acc, Rest) or something similar and avoid the reconstruction.
The modification depends on the inner workings of somefunction/1. If you want more help with that, give some code!
You can split the list into 2 sublists, if it's acceptable of course.
witerate(Fun, [Tail], Acc) ->
Fun([], Acc);
witerate(Fun, [Head | Tail], Acc) ->
Fun(Tail, Acc),
witerate(Fun, Tail, [Head | Acc]).