I am having a problem with tail in my function.I would like to get rid of the tail but I cannot think of a way to do it.I will be happy if someone may assist me figure a way out.
fun Rollists (x::nil) = [x]
| Rollists (xs) =(map hd xs)::Rollists( map tl xs);
this function,is supposed to output elements from a given list list as pairs from each list,an larger version of ListPair.zip
Generates pairs from a list of lists based upon the first list:
fun generateTuples (lol) =
let
(* Treat the ListOfLists as a database
table, with the first
list being a key value column *)
val keys = hd(lol)
(* and the remaining columns being
additional fields in its tuple *)
val records = tl(lol)
(* Pairs the key with each column
in its record *)
fun formPairs (aKey,listOfRecords) =
if null listOfRecords
then []
else [aKey,hd(hd listOfRecords)]::
(formPairs(aKey,tl(listOfRecords)))
(* Pops a row's data fields from the record *)
fun chopLists (listOfRecords)=
if null listOfRecords
then []
else tl(hd(listOfRecords))::
(chopLists(tl(listOfRecords)))
in
(* Pass the first key value to formPairs
along with all the records. Then pop
the first row off the database and call
generateTuples on the remain *)
if null keys
then []
else generateTuples(tl(keys)::(chopLists(records)))
# formPairs(hd(keys),records)
end
Example:
val list1 = [0,1,2,3,4]
val list2 = [55,66,77,88,99]
val list3 = [10,11,12,13,14]
val list4 = [555,666,777,888,999]
val lols = [list1,list2,list3,list4]
- generateTuples(lols);
val it =
[[4,99],[4,14],[4,999],[3,88],[3,13],[3,888],[2,77],[2,12],[2,777],[1,66],
[1,11],[1,666],...] : int list list
Related
Good morning,
I have a problem with coding using ocaml so I had to code a function that take on input list then add to this list an element.
But using this does'nt affect the list1 so how can I do this ?
Thank you.
let rec append list1 element list2 = match list2 with
[]-> list1
| e::l -> if ( element = e ) then e :: list1
else (append list1 element l)
;;
List are immutable in OCaml, you can't change this. You can write a function append that takes a list and returns a new list that appends an element to it.
For example, here is the prepend function that takes a list and an element and returns a new list with the given element prepended to the passed list,
let prepend xs x = x :: xs
The append function is a little bit trickier, since lists in OCaml are singly-linked, so it is easy to prepend but hard to append. To implement the append function you need an intermediate list, let's call it acc for accumulator. You then go through each element of the input list and add it to the accumulator. Since you're prepending, then once the input list is over your accumulator will have all the elements of the input list by in the reversed order, i.e., the first element (aka the head) of the acc list will be the last element of the input list. Now you what is left is to prepend the element that we want to append to the reversed acc list and reverse act. Here is the skeleton code for you
let append xs x =
let rec loop xs acc = match xs with
| ... -> ... in
loop xs []
First things first, I know how to append to a list in f#. If I have list = [1;2;3] then I can I can do something like 5 :: list and it will give me a new list [5;1;2;3].
I have written a function however that uses the exact same syntax but instead appends it to the back of the list, and I can't for the life of my figure out why. Can someone please explain to me why the function I wrote appends and item to the back of my list instead of the front?
let menu = [("pizza",17);("hotdog",5);("burger", 12);("drink",3);("milkshake",4)]
let rec insert dict key value =
match dict with
| (k,v) :: tl when k = key -> (k,v)::tl
| (k,v) :: tl -> (k,v)::insert tl key value
| [] -> (key,value) :: []
> insert menu "bacon" 22;;
val it : (string * int) list =
[("pizza", 17); ("hotdog", 5); ("burger", 12); ("drink", 3);
("milkshake", 4); ("bacon", 22)]
I don't really care one way or the other where it gets added to my list, I just don't understand why it's going on the end when I'm using the cons operator.
You are always inserting the new pair in front of an empty list, which is the last tail at the end of the actual list.
So if we consider this example:
insert [(1, 2)] 3 4
// Returns [(1, 2); (3, 4)]
[(1, 2)] can also be written like this:
(1, 2) :: []
And your code is effectively doing this:
(1, 2) :: (3, 4) :: []
Your insert is a recursive function. You go through each element until you hit the bottom the empty list. If you didn't found the element, then you return a one-element list with the element added. Because your are at the bottom, now all elements before you walked through your list gets added on top of this.
So overall, your new item gets added at the the end, or appended.
I was trying to implement k-out-of-N at SML so "pick(3,[1,2,3,4])" will return [[1,2,3],[1,3,4]...] (all the K-size picks out of N elements)
I used List.map which I figured it calls the function and apply it on each element.
Really can't figure out why when typing the input "pick(3,[1,2,3,4,5])" ,for example, it return an empty list.
My first thought was that it's because of the initial terms (choose (_,[]) = [])
But changing it didn't work as well.
The signature is ok (val pick = fn : int * 'a list -> 'a list list).
fun pick (_,[]) = []
| pick (0,_) = []
| pick (n,hd::tl) =
let
val with_hd = List.map (fn x => hd::x) (pick(n-1,tl))
val without_hd = pick(n,tl)
in
with_hd#without_hd
end;
The problem is related to your suspicion – the base cases are incorrect in that they always produce the empty list, and mapping fn x => hd::x onto the empty list produces the empty list.
Picking zero elements from anything should succeed, and produce the empty list.
That is, pick (0, _) = [[]] — a list with one element, which is the empty list.
You also need to rearrange the cases since pick(n, []) succeeds for n = 0 but not for any other n.
In summary,
fun pick (0, _) = [[]]
| pick (_, []) = []
with the rest of the function exactly as before.
I have 2 Lists as mentioned below:
val L1 = List[(Int,Int,String)]
val L2 = List[(Int,Int,String)]
I want to join these 2 lists on the basis of 1st and 2nd Int element in a way that result list must have 4 elements (Int,Int,String,String).
val joinedList = List[(Int, Int, String, String)]
where last 2 String elements will be string from L1 and string from L2.
Ex:-
val L1 = List((1,1,"one"), (2,2,"two"))
val L2 = List((2,2,"twice"), (3,3,"thrice"))
Output List ->
val joinedList = List((1,1,"one","--"),(2,2,"two","twice"), (3,3,"--","thrice"))
Kindly suggest a way to achieve that in scala.
First you want to get it into Maps, so it's easier to look up, then you can just map over all the keys:
val L1Map = L1.map{case (x,y,z) => ((x,y) -> z)}.toMap
val L2Map = L2.map{case (x,y,z) => ((x,y) -> z)}.toMap
val allKeys = L1Map.keySet ++ L2Map.keySet
val result = allKeys map {case (x,y) =>
(x, y, L1Map.getOrElse((x,y), "--"), L2Map.getOrElse((x,y), "--"))
}
That gives you an unsorted Set as a result. If you need a List, you can convert it back and sort it as necessary.
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.)