So, I have to do this task
permute: ‘a list list -> int list -> int list ->
‘a list list =
that takes a square n×n matrix represented as a list of lists as the first parameter
and returns a matrix with rows in order given by the list of integers as the
second parameter and columns in order given by the list of integers as the third
parameter. The second and third parameter each represent a permutation of
the first n numbers.
Example:
permute [[1;2;3];[4;5;6];[7;8;9]] [2;3;1] [1;3;2];;
- : int = [[4;6;5];[7;9;8];[1;3;2]]
My code so far is like this:
let fun a i =
let elem id = List.nth a (id-1) in
List.map elem i
This works as a list but I need it to work as a list of lists.
Any help would be appreciated.
(You can't have a function named fun in OCaml. fun is a so-called reserved word. I will rename it to perm.)
Your function has this type:
val perm : 'a list -> int list -> 'a list = <fun>
In other words, it works for any list at all. This includes a list of lists.
For example:
# perm [1;2;3;4] [4;3;2;1];;
- : int list = [4; 3; 2; 1]
# perm [[1;1]; [2;2]; [3;3]; [4;4]] [4;3;2;1];;
- : int list list = [[4; 4]; [3; 3]; [2; 2]; [1; 1]]
So, the hint is to map this perm function over the initial list, then to apply this perm function again to the result.
Related
I started learning F# yesterday and am struggling a bit with all the new functional programming.
I am trying to understand this implementation of merge sort which uses a split function. The split function is defined as:
let rec split = function
| [] -> ([], [])
| [a] -> ([a], [])
| a :: b :: cs -> let (r, s) = split cs
in (a :: r, b :: s)
The way I understand it, we take a list and return a tuple of lists, having split the list into two halves. If we pattern match on the empty list we return a tuple of empty lists, if we match on a list with one element we return a tuple with the list and an empty list, but the recursive case is eluding me.
a :: b :: cs means a prepended to b prepended to cs, right? So this is the case where the list has at least 3 elements? If so, we return two values, r and s, but I have not seen this "in" keyword used before. As far as I can tell, we prepend a, the first element, to r and b, the second element, to s, and then split on the remainder of the list, cs. But this does not appear to split the list in half to me.
Could anybody please help explain how the recursive case works? Thanks a lot.
You can ignore the in keyword in this case, so you can read the last case as just:
| a :: b :: cs ->
let (r, s) = split cs
(a :: r, b :: s)
Note that this will match any list of length 2 or greater, not 3 as you originally thought. When the list has exactly two elements, cs will be the empty list.
So what's going on in this case is:
If the list has at least 2 elements:
Name the first element a
Name the second element b
Name the rest of the list cs (even if it's empty)
Split cs recursively, which gives us two new lists, r and s
Create two more new lists:
One with a on the front of r
The other with b on the front of s
Return the two new lists
You can see this in operation if you call the function like this:
split [] |> printfn "%A" // [],[]
split [1] |> printfn "%A" // [1],[]
split [1; 2] |> printfn "%A" // [1],[2]
split [1; 2; 3] |> printfn "%A" // [1; 3],[2]
split [1; 2; 3; 4] |> printfn "%A" // [1; 3],[2; 4]
split [1; 2; 3; 4; 5] |> printfn "%A" // [1; 3; 5],[2; 4]
Update: What exactly does in do?
The in keyword is just a way to put a let-binding inside an expression. So, for example, we could write let x = 5 in x + x, which is an expression that has the value 10. This syntax is inherited from OCaml, and is still useful when you want to write the entire expression on one line.
In modern F#, we can use whitespace/indentation instead, by replacing the in keyword with a newline. So nowadays, we would usually write this expression as follows:
let x = 5
x + x
The two forms are semantically equivalent. More details here.
cs is [] when there are only two items in the list. When there are 3 or more items in the list then it recurses where cs is the list without the first two items. When there is only one item it returns [a],[] and when the list is empty it returns [],[] .
What approach would you use to generate the set of NxN matrices containing only zeros and ones which represents all possible distinct combinations?
let matrix Array2D.init N N (fun x y -> something)
If you don't know F# then pseudocode will be a contribution aswell.
So what I want is a list/array of all the distinct matrix combinations
So, I think the hard part is the generating the list of elements. We can do it recursively.
The base case is easy. For a 1x1 matrix, you have 1 element which can only have two combinations: [|[|0|]; [|1|]|].
For a 2x2 elements, we have 2^2 = 4 elements. Each one of these can be either 1 or 0, so there are 2^4 = 16 combinations possible. To get all the combinations possible for this 2x2 array, we can think of it as an array of length 4.
But first, let's think about an array of length 2. Then we have to find all the combinations between [|[|0|]; [|1|]|] and [|[|0|]; [|1|]|]. This would be [|[|0; 0|]; [|0;1|]; [|1;0|]; [|1; 1|]|]. Luckily, there's a function called Array.allPairs which will generate the array of all possible combinations between two arrays, which already does this for us!
So, we can apply Array.allPairs to each element of our array of length 4 sequentially to get all the possible combinations for the entire matrix using Array.reduce. I make a function called pairsToArray to basically flatten the data structure.
let pairsToArray x = Array.concat [|fst x; snd x|]
let rec binary N =
match N with
| 0 -> [||]
| 1 -> [|[|0|]; [|1|]|]
| n -> let elements = n*n
let combinations = Array.init elements (fun i -> binary 1)
let result = Array.reduce (fun acc i -> Array.allPairs acc i |> Array.map pairsToArray) combinations
result
Now, all that remains is converting this to a Array2D.
Something like should do the trick
let c = binary 2
c |> Array.map (fun i -> Array2D.init 2 2 (fun j k -> i.[j+k*2]))
for the 2x2 case
Maybe something like this
let rec addOne (N1: int, N2: int) (M: int[,]) (i: int, j: int)=
if M.[i,j] = 0
then M.[i,j] <- 1
true
else M.[i,j] <- 0
let newi, newj =
if i < N1-1
then (i+1,j)
else (0,j+1)
if newj = N2
then false
else addOne (N1, N2) M (newi,newj)
combined with this
let N = 3
let M: int[,] = Array2D.zeroCreate N N
let mylist =
[ yield M;
while addOne (N,N) M (0,0)
do yield Array2D.copy M ]
I don't know if it makes sense.
It is a method to find the "next" matrix, and then make a list of all the matrices that we encounter that way.
edit: replaced bool with int (0 and 1) to better fit the original question.
I have this matrix:
let arr = Array.make_matrix 4 4 0;;
and what to check if all elements are 0.
I heard of the function for_all but I can't quite figure it out how to use it with a matrix, since it expects an int array or a int list.
According to the documentation (https://caml.inria.fr/pub/docs/manual-ocaml/libref/Array.html), here is everything you need to know:
val for_all : ('a -> bool) -> 'a array -> bool
Array.for_all p [|a1; ...; an|] checks if all elements of the array satisfy the predicate p. That is, it returns (p a1) && (p a2) && ... && (p an).
Example: Array.for_all ((=) 0) has type int array -> bool and checks if all elements are zero.
A matrix is an array of arrays (or an array of rows if you prefer). So you need to execute a for_all on each one of the rows to check that all elements of the row are zero, and another outer for_all to check that all the for_alls over rows are true:
let arr = Array.make_matrix 4 4 0 in
Array.for_all (fun row ->
Array.for_all ((=) 0) row) arr
So I'm trying to sort this list of integers so that all the even numbers are in the front and the odds are all in the back. I have my program now which works for the most part but it keeps reversing the order of my odds numbers which I don't want it to do. E.g. given the input [1;2;3;4;5;6] I would like to get [2;4;6;1;3;5], but I'm getting [2;4;6;5;3;1] Any help is greatly appreciated!
let rec evens (xl:int list) (odd:int list) : int list =
match xl with
| [] -> []
| h::t ->
if h mod 2 = 0
then (h)::evens t odd
else
evens t odd#[(h)]
The main part of your current code parses like this:
if h mod 2 = 0 then
h :: (evens t odd)
else
(evens t odd) # [h]
It says this: if the next number h is even, sort out the rest of the list, then add h to the front. If the next number h is odd, sort out the rest of the list, then add h to the end. So it follows that the odd numbers will be reversed at the end.
It's worth noting that your parameter named odd is always passed along unchanged, and hence will always be an empty list (or whatever you pass as the second parameter of evens).
When I first looked at your code, I assumed you were planning to accumulate the odd numbers in the odd parameter. If you want to do that, you need to make two changes. First you need to rewrite like this:
if h mod 2 = 0 then
h :: evens t odd
else
evens t (odd # [h])
The precedence rules of OCaml require the parentheses if you want to add h to the odd parameter. Your current code adds h to the returned result of evens (as above).
This rewrite will accumulate the odd numbers, in order, in the odd parameter.
Then you need to actually use the odd parameter at the end of the recursion. I.e., you need to use it when xl is empty.
The standard library has a neat solution to your problem.
List.partition (fun x -> x mod 2 = 0) [1;2;3;4;5;6]
- : int list * int list = ([2; 4; 6], [1; 3; 5])
The partition function splits your list into a tuple of two lists:
The list of elements that validate a predicate;
The list of elements that don't.
All you have to do is combine those lists together.
let even_first l =
let evens, odds = List.partition (fun x -> x mod 2 = 0) l in
evens # odds
If you want to make it more generic, let the predicate be an argument:
let order_by_predicate ~f l =
let valid, invalid = List.partition f l in
valid # invalid
I am working on homework and the problem is where we get 2 int lists of the same size, and then add the numbers together. Example as follows.
vecadd [1;2;3] [4;5;6];; would return [5;7;9]
I am new to this and I need to keep my code pretty simple so I can learn from it. I have this so far. (Not working)
let rec vecadd L K =
if L <> [] then vecadd ((L.Head+K.Head)::L) K else [];;
I essentially want to just replace the first list (L) with the added numbers. Also I have tried to code it a different way using the match cases.
let rec vecadd L K =
match L with
|[]->[]
|h::[]-> L
|h::t -> vecadd ((h+K.Head)::[]) K
Neither of them are working and I would appreciate any help I can get.
First, your idea about modifying the first list instead of returning a new one is misguided. Mutation (i.e. modifying data in place) is the number one reason for bugs today (used to be goto, but that's been banned for a long time now). Making every operation produce a new datum rather than modify existing ones is much, much safer. And in some cases it may be even more performant, quite counterintuitively (see below).
Second, the way you're trying to do it, you're not doing what you think you're doing. The double-colon doesn't mean "modify the first item". It means "attach an item in front". For example:
let a = [1; 2; 3]
let b = 4 :: a // b = [4; 1; 2; 3]
let c = 5 :: b // c = [5; 4; 1; 2; 3]
That's how lists are actually built: you start with a empty list and prepend items to it. The [1; 2; 3] syntax you're using is just a syntactic sugar for that. That is, [1; 2; 3] === 1::2::3::[].
So how do I modify a list, you ask? The answer is, you don't! F# lists are immutable data structures. Once you've created a list, you can't modify it.
This immutability allows for an interesting optimization. Take another look at the example I posted above, the one with three lists a, b, and c. How many cells of memory do you think these three lists occupy? The first list has 3 items, second - 4, and third - 5, so the total amount of memory taken must be 12, right? Wrong! The total amount of memory taken up by these three lists is actually just 5 cells. This is because list b is not a block of memory of length 4, but rather just the number 4 paired with a pointer to the list a. The number 4 is called "head" of the list, and the pointer is called its "tail". Similarly, the list c consists of one number 5 (its "head") and a pointer to list b, which is its "tail".
If lists were not immutable, one couldn't organize them like this: what if somebody modifies my tail? Lists would have to be copied every time (google "defensive copy").
So the only way to do with lists is to return a new one. What you're trying to do can be described like this: if the input lists are empty, the result is an empty list; otherwise, the result is the sum of tails prepended with the sum of heads. You can write this down in F# almost verbatim:
let rec add a b =
match a, b with
| [], [] -> [] // sum of two empty lists is an empty list
| a::atail, b::btail -> (a + b) :: (add atail btail) // sum of non-empty lists is sum of their tails prepended with sum of their heads
Note that this program is incomplete: it doesn't specify what the result should be when one input is empty and the other is not. The compiler will generate a warning about this. I'll leave the solution as an exercise for the reader.
You can map over both lists together with List.map2 (see the docs)
It goes over both lists pairwise and you can give it a function (the first parameter of List.map2) to apply to every pair of elements from the lists. And that generates the new list.
let a = [1;2;3]
let b = [4;5;6]
let vecadd = List.map2 (+)
let result = vecadd a b
printfn "%A" result
And if you want't to do more work 'yourself' something like this?
let a = [1;2;3]
let b = [4;5;6]
let vecadd l1 l2 =
let rec step l1 l2 acc =
match l1, l2 with
| [], [] -> acc
| [], _ | _, [] -> failwithf "one list is bigger than the other"
| h1 :: t1, h2 :: t2 -> step t1 t2 (List.append acc [(h1 + h2)])
step l1 l2 []
let result = vecadd a b
printfn "%A" result
The step function is a recursive function that takes two lists and an accumulator to carry the result.
In the last match statement it does three things
Sum the head of both lists
Add the result to the accumulator
Recursively call itself with the new accumulator and the tails of the lists
The first match returns the accumulator when the remaining lists are empty
The second match returns an error when one of the lists is longer than the other.
The accumulator is returned as the result when the remaining lists are empty.
The call step l1 l2 [] kicks it off with the two supplied lists and an empty accumulator.
I have done this for crossing two lists (multiply items with same index together):
let items = [1I..50_000I]
let another = [1I..50_000I]
let rec cross a b =
let rec cross_internal = function
| r, [], [] -> r
| r, [], t -> r#t
| r, t, [] -> r#t
| r, head::t1, head2::t2 -> cross_internal(r#[head*head2], t1, t2)
cross_internal([], a, b)
let result = cross items another
result |> printf "%A,"
Note: not really performant. There are list object creations at each step which is horrible. Ideally the inner function cross_internal must create a mutable list and keep updating it.
Note2: my ranges were larger initially and using bigint (hence the I suffix in 50_000) but then reduced the sample code above to just 50,500 elements.