Remove all empty lists from a list of lists Ocaml - list

please help.
I am trying to write two non-recursive functions in OCaml (a list of lists contains elements that are lists themselves)
clear l which takes a list of lists as an argument and returns the list of lists without empty lists if there are any.
Example: clear [[2];[];[];[3;4;6];[6;5];[]]
will returns
[[2];[3;4;6];[6;5]]
sort_length l that sorts the elements of this list l according to their length. E.g. sort_length [[2];[];[3];[6;5]] returns [[];[2];[3];[6;5]]
I am only allowed to use these predefined functions: List.filter, List.sort, List.hd, List.tl, List.length and no others.
Thanks
For the second function, I have tried this so far, but I used map which is not allowed
let rec insert cmp e = function
| [] -> [e]
| h :: t as l -> if cmp e h <= 0 then e :: l else h :: insert cmp e t
let rec sort cmp = function
| [] -> []
| h :: t -> insert cmp h (sort cmp t)
let sort_length l =
let l = List.map (fun list -> List.length list, list) l in
let l = sort (fun a b -> compare (fst a) (fst b)) l in
List.map snd l;;
Thanks

As mentioned here: https://ocaml.org/api/List.html#VALfilter, List.filter returns all the elements of the list that satisfy the given predicate. So you must write a predicate that describes a list that is not empty. Another way of saying that a list is not empty is to say that "its size is greater than zero". So it would be possible to formulate clear in this way:
let clear list =
let is_not_empty l = (List.length l) > 0 in
List.filter is_not_empty list
Small edit
As mentioned by Chris Dutton, using List.length may be inefficient. Another approach would be to express is_not_empty in this way:
let is_not_empty = function
| [] -> false
| _ -> true
This approach is "better" because it does not require going through the whole list to see if it is empty or not.
For the second point, the List.sort function takes a comparison function between two elements ('a -> 'a -> int), here the comparison must act on the size of the lists.
In other words, the size of the two lists observed must be compared. One way to do this would be to use Int.compare (https://ocaml.org/api/Int.html#VALcompare) on the size of the two observed lists. For example:
let sort_length list =
let compare_length a b =
let la = List.length a in
let lb = List.length b in
Int.compare la lb
in
List.sort compare_length list
There are more concise ways of writing these two functions but these implementations should be fairly clear.

Related

F# Returning the 3 element tuple with the largest middle value from the list of tuples

I have a homework practice problem and I am new to F# and the syntax is so confusing, I do not know where to start
For example, If I have a list of tuples of increasing values :
let tupleList = [(1,2,3);(10,12,15);(9,10,20)]
I should write a function that returns a tuple that has the largest middle value.
So the function should return :
(10,12,15)
Any hints on what should I consider, read on the Internet, or research, or any other tips to help me learn how to do this is appreciated!
Thank you!
You should probably read a book on F# or work through https://fsharpforfunandprofit.com/
You can use List.max or List.maxBy to get the maximum in a list. Because you have a three element tuple, you will need to deconstruct it (as there is no function to access the nth element of a tuple, only the first or the second one). Once you exposed the middle value you can run maxby on it, and get rid of the unnecessary parts.
let tupleList = [(1,2,3);(10,12,15);(9,10,20)]
tupleList
|> List.map (fun (a,b,c) -> (b, (a,b,c)))
|> List.maxBy fst
|> snd
val it : int * int * int = (10, 12, 15)
If none of built-in function can be used, then you can use either (1) mutable variables and while loop or (2) recursion.
Since you are learning functional programming, it is very likely that your professor will prefer recursion. Here is the solution:
let max2 (a,b,c) (x,y,z) = if b > y then (a,b,c) else (x,y,z)
let maxMany tuples =
let rec loop currentMaxTuple remainTuples =
match remainTuples with
| [] -> currentMaxTuple
| tuple :: rest ->
let newMaxTuple = max2 currentMaxTuple tuple
loop newMaxTuple rest
match tuples with
| [] -> None
| head :: rest -> Some (loop head rest)
let tupleList = [(1,2,3);(10,12,15);(9,10,20)]
maxMany tupleList |> printfn "%A"
Slightly different from #Nghia Bui's solution, you can use pattern matching to compare tuples items.
let maxSnd tuples =
let rec loop list tuple =
match list, tuple with
| [], _ -> tuple
| (x, y, z) :: xs, (a, b, c) ->
if y < b then (a, b, c) else (x, y, z)
|> loop xs
match tuples with
| [] -> invalidArg "tuples" "Empty list"; 0, 0, 0
| x :: xs -> loop xs x
A little late but anyway:
let maxByMiddle data =
let rec find lst =
match lst with
| [] -> Error("No entries in list")
| [a, b, c] -> Ok(a, b, c)
| (_, bmax, _)::(a, b, c)::tail when b > bmax -> find ((a, b, c)::tail)
| maxima::_::tail -> find (maxima::tail)
find data

How to double elements in an F# list and set them in a new list

I am very new to F# and functional programming in general, and would like to recursively create a function that takes a list, and doubles all elements.
This is what I used to search for a spacific element, but im not sure how exactly I can change it to do what I need.
let rec returnN n theList =
match n, theList with
| 0, (head::_) -> head
| _, (_::theList') -> returnN (n - 1) theList'
| _, [] -> invalidArg "n" "n is larger then list length"
let list1 = [5; 10; 15; 20; 50; 25; 30]
printfn "%d" (returnN 3 list1 )
Is there a way for me to augment this to do what I need to?
I would like to take you through the thinking process.
Step 1. I need a recursive function that takes a list and doubles all the elements:
So, let's implement this in a naive way:
let rec doubleAll list =
match list with
| [] -> []
| hd :: tl -> hd * 2 :: doubleAll tl
Hopefully this logic is quite simple:
If we have an empty list, we return another empty list.
If we have a list with at least one element, we double the element and then prepend that to the result of calling the doubleAll function on the tail of the list.
Step 2. Actually, there are two things going on here:
I want a function that lets me apply another function to each element of a list.
In this case, I want that function to be "multiply by 2".
So, now we have two functions, let's do a simple implementation like this:
let rec map f list =
match list with
| [] -> []
| hd :: tl -> f hd :: map f tl
let doubleAll list = map (fun x -> x * 2) list
Step 3. Actually, the idea of map is such a common one that it's already built into the F# standard library, see List.map
So, all we need to do is this:
let doubleAll list = List.map (fun x -> x * 2) list

OCaml code that works on 2 lists. Is there a better way of doing this

I have to iterate over 2 lists. One starts off as a list of empty sublists and the second one has the max length for each of the sublists that are in the first one.
Example; list1 = [[];[];[];]; list2 = [1;2;3]
I need to fill out the empty sublists in list1 ensuring that the length of the sublists never exceed the corresponding integer in list2. To that end, I wrote the following function, that given an element, elem and 2 two lists list and list, will fill out the sublists.
let mapfn elem list1 list2=
let d = ref 1 in
List.map2 (fun a b -> if ((List.length a) < b) && (!d=1)
then (incr d ; List.append a [elem])
else a )
list1 list2
;;
I can now call this function repeatedly on the elements of a list and get the final answer I need
This function works as expected. But I am little bothered by the need to use the int ref d.
Is there a better way for me to do this.
I always find it worthwhile to split the problem into byte-sized pieces that can be composed together to form a solution. You want to pad or truncate lists to a given length; this is easy to do in two steps, first pad, then truncate:
let all x = let rec xs = x :: xs in xs
let rec take n = function
| [] -> []
| _ when n = 0 -> []
| x :: xs -> x :: take (pred n) xs
all creates an infinite list by repeating a value, while take extracts the prefix sublist of at most the given length. With these two, padding and truncating is very straightforwad:
let pad_trim e n l = take n (l # all e)
(it might be a bit surprising that this actually works in a strict language like OCaml). With that defined, your required function is simply:
let mapfn elem list1 list2 = List.map2 (pad_trim elem) list2 list1
that is, taking the second list as a list of specified lengths, pad each of the lists in the first list to that length with the supplied padding element. For instance, mapfn 42 [[];[];[]] [1;2;3] gives [[42]; [42; 42]; [42; 42; 42]]. If this is not what you need, you can tweak the parts and their assembly to suit your requirements.
Are you looking for something like that?
let fill_list elem lengths =
let rec fill acc = function
| 0 -> acc
| n -> fill (elem :: acc) (n - 1) in
let accumulators = List.map (fun _ -> []) lengths in
List.map2 fill accumulators lengths
(* toplevel test *)
# let test = fill_list 42 [1; 3];;
val test : int list list = [[42]; [42; 42; 42]]
(I couldn't make sense of the first list of empty lists in your question, but I suspect it may be the accumulators for the tail-rec fill function.)

Combine Lists with Same Heads in a 2D List (OCaml)

I'm working with a list of lists in OCaml, and I'm trying to write a function that combines all of the lists that share the same head. This is what I have so far, and I make use of the List.hd built-in function, but not surprisingly, I'm getting the failure "hd" error:
let rec combineSameHead list nlist = match list with
| [] -> []#nlist
| h::t -> if List.hd h = List.hd (List.hd t)
then combineSameHead t nlist#uniq(h#(List.hd t))
else combineSameHead t nlist#h;;
So for example, if I have this list:
[[Sentence; Quiet]; [Sentence; Grunt]; [Sentence; Shout]]
I want to combine it into:
[[Sentence; Quiet; Grunt; Shout]]
The function uniq I wrote just removes all duplicates within a list. Please let me know how I would go about completing this. Thanks in advance!
For one thing, I generally avoid functions like List.hd, as pattern maching is usually clearer and less error-prone. In this case, your if can be replaced with guarded patterns (a when clause after the pattern). I think what is happening to cause your error is that your code fails when t is []; guarded patterns help avoid this by making the cases more explicit. So, you can do (x::xs)::(y::ys)::t when x = y as a clause in your match expression to check that the heads of the first two elements of the list are the same. It's not uncommon in OCaml to have several successive patterns which are identical except for guards.
Further things: you don't need []#nlist - it's the same as just writing nlist.
Also, it looks like your nlist#h and similar expressions are trying to concatenate lists before passing them to the recursive call; in OCaml, however, function application binds more tightly than any operator, so it actually appends the result of the recursive call to h.
I don't, off-hand, have a correct version of the function. But I would start by writing it with guarded patterns, and then see how far that gets you in working it out.
Your intended operation has a simple recursive description: recursively process the tail of your list, then perform an "insert" operation with the head which looks for a list that begins with the same head and, if found, inserts all elements but the head, and otherwise appends it at the end. You can then reverse the result to get your intended list of list.
In OCaml, this algorithm would look like this:
let process list =
let rec insert (head,tail) = function
| [] -> head :: tail
| h :: t ->
match h with
| hh :: tt when hh = head -> (hh :: (tail # t)) :: t
| _ -> h :: insert (head,tail) t
in
let rec aux = function
| [] -> []
| [] :: t -> aux t
| (head :: tail) :: t -> insert (head,tail) (aux t)
in
List.rev (aux list)
Consider using a Map or a hash table to keep track of the heads and the elements found for each head. The nlist auxiliary list isn't very helpful if lists with the same heads aren't adjacent, as in this example:
# combineSameHead [["A"; "a0"; "a1"]; ["B"; "b0"]; ["A"; "a2"]]
- : list (list string) = [["A"; "a0"; "a1"; "a2"]; ["B"; "b0"]]
I probably would have done something along the lines of what antonakos suggested. It would totally avoid the O(n) cost of searching in a list. You may also find that using a StringSet.t StringMap.t be easier on further processing. Of course, readability is paramount, and I still find this hold under that criteria.
module OrderedString =
struct
type t = string
let compare = Pervasives.compare
end
module StringMap = Map.Make (OrderedString)
module StringSet = Set.Make (OrderedString)
let merge_same_heads lsts =
let add_single map = function
| hd::tl when StringMap.mem hd map ->
let set = StringMap.find hd map in
let set = List.fold_right StringSet.add tl set in
StringMap.add hd set map
| hd::tl ->
let set = List.fold_right StringSet.add tl StringSet.empty in
StringMap.add hd set map
| [] ->
map
in
let map = List.fold_left add_single StringMap.empty lsts in
StringMap.fold (fun k v acc-> (k::(StringSet.elements v))::acc) map []
You can do a lot just using the standard library:
(* compares the head of a list to a supplied value. Used to partition a lists of lists *)
let partPred x = function h::_ -> h = x
| _ -> false
let rec combineHeads = function [] -> []
| []::t -> combineHeads t (* skip empty lists *)
| (hh::_ as h)::t -> let r, l = List.partition (partPred hh) t in (* split into lists with the same head as the first, and lists with different heads *)
(List.fold_left (fun x y -> x # (List.tl y)) h r)::(combineHeads l) (* combine all the lists with the same head, then recurse on the remaining lists *)
combineHeads [[1;2;3];[1;4;5;];[2;3;4];[1];[1;5;7];[2;5];[3;4;6]];;
- : int list list = [[1; 2; 3; 4; 5; 5; 7]; [2; 3; 4; 5]; [3; 4; 6]]
This won't be fast (partition, fold_left and concat are all O(n)) however.

ocaml using List.map iterate over list

is there a way to iterate list over the list through List.map?
I know List.map takes single function and list and produce a list that the function applies to all elements. But what if i have a list of function to apply a list and produce list of the list ?
Your question is not very clear, however as far as I understand it, you have a list of functions and a list of values. If you want to apply all functions to all elements then you can write this:
(* // To get one nested list (of results of all functions) for each element *)
List.map (fun element ->
List.map (fun f -> f element) functions) inputs
(* // To get one nested list (of results for all elements) for each function *)
List.map (fun f ->
List.map (fun element -> f element) inputs) functions
In case this is not what you wanted, could you try clarifying the question a little bit (perhaps some concrete example would help)?
Are you allowed to use List.map2? Because then this is simple:
let lista = [(fun x -> x + 1); (fun x -> x + 2); (fun x -> x + 3)];;
let listb = [1; 1; 1];;
let listc = List.map2 (fun a b -> (a b)) lista listb;;
The output would be [2; 3; 4]
Edit: wait, I think I read your problem wrong. You want to get a list of lists, where each list contains a list of a function applied to the initial list? In other words, for the lista and listb above, you'd get:
[[2;2;2];[3;3;3];[4;4;4]]
Is this correct?
You can try this :
let rec fmap fct_list list = match fct_list with
[] -> //you do nothing or raise sth
head::tail -> List.map head list :: fmap tail list;;