Practicing on matrix - Ocaml - functional-programming

I am practicing on matrix at the moment but I am not really sure on the most efficient way to resolve some of the problems I encounter.
My first "problem" is to optimize a function. What I try to do is to iterate trough the 'a matrix which is a 'a array array.
For each line identified by an integer between 0 and 4 (the matrix has a size of (5,10)), I count how many "one" there is.
I had to split it in three different functions but I was wondering if there is any more optimized way to solve this problem ?
let count m i =
let ret=Array.fold_left (fun x y -> if y=1 then x+1 else x) 0 (m.(i)) in
ret;;
let rec clear l =
match l with
|[]->[]
|(a,b)::[]->if b=0 then [] else (a,b)::[]
|(a,b)::c->if b=0 then clear c else (a,b)::clear c;;
let all_moves s =
match s with
|(a,_)->clear[(0,count a 0);(1,count a 1);(2,count a 2);(3,count a 3);(4,count a 4)];;
Second of all, my main problem is to iterate through the entire matrix at once.
I'm trying to count all the 1 in the matrix except for the line identified by param "i".
I tried several things but I'm really stuck at the moment.
let countall m i =
let ret=Array.fold_left (fun x y -> if pos != i then x + y else ())
(Array.fold_left (fun x y -> if y=1 then x+1 else x) 0 (m.(i)))
0 m in
ret;;
I would like to thank you in advance for your help and I thought I might give a matrix for you to test my functions:
let c = [|[|1; 1; 1; 1; 1; 0; 0; 0; 0; 0|]; [|1; 1; 1; 1; 1; 1; 1; 1; 0; 0|];
[|1; 1; 1; 1; 1; 1; 1; 1; 1; 0|]; [|1; 0; 0; 0; 0; 0; 0; 0; 0; 0|];
[|1; 1; 1; 1; 1; 1; 1; 1; 1; 1|]|]
Sincerely yours,
Rama

Some pointers:
Expressions of the form let ret = expr in ret can be simplified to expr. And the reverse application operator |> can often be used to elide trivial let expressions.
If a function starts with a match expression that has just a single clause, that clause can often be rolled into the function signature. E.g. let all_moves s = match s with (a, _) -> ... becomes `let all_moves (a, _) = ...'.
The Array and List modules have more than just fold functions (and alternative standard libraries, such as Core, Batteries, or ExtLib add more functionality to them) that can be used to simplify a lot of Array/List processing.
Example:
let count_ones row =
Array.fold_left (fun c x -> if x=1 then c+1 else c) 0 row
let all_moves (mat, _) =
Array.mapi (fun i row -> (i, count_ones row)) mat
|> Array.to_list |> List.filter (fun (_, c) -> c != 0)
I'm not 100% sure what the intended semantics of countall are, but if I'm understanding it correctly, the following should work (it follows the basic structure of your attempted solution, but relies on mapi instead of fold_left, which is a better fit):
let countall mat k =
Array.mapi (fun i row -> if i = k then 0 else count_ones row) mat
|> Array.fold_left (+) 0
This function can be implemented in different ways, too, e.g.:
let countall mat k =
Array.(append (sub mat 0 k) (sub mat (k+1) (length mat - k - 1)))
|> Array.map count_ones |> Array.fold_left (+) 0
In this variant, I'm using a local open Array.(expr) so that I don't have to prefix every single array operation with Array.. Also, in both versions (+) is a way to write the plus operator as a function with two arguments, and is roughly equivalent to writing (fun x y -> x + y) in its place.

Maybe that could help you
let countall m i =
snd (
Array.fold_left (fun (lg,c) v ->
let c=
if lg = i then c
else
Array.fold_left (fun c xy -> if xy=1 then c+1 else c) c v
in
(lg+1,c)
) (0,0) m
)
;;
Test
# countall c 0;;
- : int = 28

Related

For Loop Over a Recursive Call Ocaml

I'm working on an implementation of prime decomposition in OCaml. I am not a functional programmer; Below is my code. The prime decomposition happens recursively in the prime_part function. primes is the list of primes from 0 to num. The goal here being that I could type prime_part into the OCaml interpreter and have it spit out when n = 20, k = 1.
2 + 3 + 7
5 + 7
I adapted is_prime and all_primes from an OCaml tutorial. all_primes will need to be called to generate a list of primes up to b prior to prime_part being called.
(* adapted from http://www.ocaml.org/learn/tutorials/99problems.html *)
let is_prime n =
let n = abs n in
let rec is_not_divisor d =
d * d > n || (n mod d <> 0 && is_not_divisor (d+1)) in
n <> 1 && is_not_divisor 2;;
let rec all_primes a b =
if a > b then [] else
let rest = all_primes (a + 1) b in
if is_prime a then a :: rest else rest;;
let f elem =
Printf.printf "%d + " elem
let rec prime_part n k lst primes =
let h elem =
if elem > k then
append_item lst elem;
prime_part (n-elem) elem lst primes in
if n == 0 then begin
List.iter f lst;
Printf.printf "\n";
()
end
else
if n <= k then
()
else
List.iter h primes;
();;
let main num =
prime_part num 1 [] (all_primes 2 num)
I'm largely confused with the reclusive nature with the for loop. I see that List.ittr is the OCaml way, but I lose access to my variables if I define another function for List.ittr. I need access to those variables to recursively call prime_part. What is a better way of doing this?
I can articulate in Ruby what I'm trying to accomplish with OCaml. n = any number, k = 1, lst = [], primes = a list of prime number 0 to n
def prime_part_constructive(n, k, lst, primes)
if n == 0
print(lst.join(' + '))
puts()
end
if n <= k
return
end
primes.each{ |i|
next if i <= k
prime_part_constructive(n - i, i, lst+[i], primes)
}
end
Here are a few comments on your code.
You can define nested functions in OCaml. Nested functions have access to all previously defined names. So you can use List.iter without losing access to your local variables.
I don't see any reason that your function prime_part_constructive returns an integer value. It would be more idiomatic in OCaml for it to return the value (), known as "unit". This is the value returned by functions that are called for their side effects (such as printing values).
The notation a.(i) is for accessing arrays, not lists. Lists and arrays are not the same in OCaml. If you replace your for with List.iter you won't have to worry about this.
To concatenate two lists, use the # operator. The notation lst.concat doesn't make sense in OCaml.
Update
Here's how it looks to have a nested function. This made up function takes a number n and a list of ints, then writes out the value of each element of the list multiplied by n.
let write_mults n lst =
let write1 m = Printf.printf " %d" (m * n) in
List.iter write1 lst
The write1 function is a nested function. Note that it has access to the value of n.
Update 2
Here's what I got when I wrote up the function:
let prime_part n primes =
let rec go residue k lst accum =
if residue < 0 then
accum
else if residue = 0 then
lst :: accum
else
let f a p =
if p <= k then a
else go (residue - p) p (p :: lst) a
in
List.fold_left f accum primes
in
go n 1 [] []
It works for your example:
val prime_part : int -> int list -> int list list = <fun>
# prime_part 12 [2;3;5;7;11];;
- : int list list = [[7; 5]; [7; 3; 2]]
Note that this function returns the list of partitions. This is much more useful (and functional) than writing them out (IMHO).

Tail Recursivity in F# : Inversions with Quicksort

Hi i have some difficulty in understanding tail-recursivity. I know thats it's important to avoid infinite loops and also for memory usage. I've seen some examples on simple functions like Fibonacci in "Expert in F#", but I don't think i've seen code when the result is something different than just a number.
What would be the accumulator then ? i'm not sure...
Here is a recursive function that I've written. It counts the number of inversions in an array, using the quicksort algorithm. [it's taken from an exercise of the Coursera MOOC Algo I by Stanford]
I'd be grateful if somebody could explain how to make that tail recursive.
[Also, i've translated that code from imperative code, as i had written that in R before, so the style is not functional at all...]
another question: is the syntax correct, A being a (mutable) array, i've written let A = .... everywhere ?
is A <- .... better / the same ?
open System.IO
open System
let X = [|57; 97; 17; 31; 54; 98; 87; 27; 89; 81; 18; 70; 3; 34; 63; 100; 46; 30; 99;
10; 33; 65; 96; 38; 48; 80; 95; 6; 16; 19; 56; 61; 1; 47; 12; 73; 49; 41;
37; 40; 59; 67; 93; 26; 75; 44; 58; 66; 8; 55; 94; 74; 83; 7; 15; 86; 42;
50; 5; 22; 90; 13; 69; 53; 43; 24; 92; 51; 23; 39; 78; 85; 4; 25; 52; 36;
60; 68; 9; 64; 79; 14; 45; 2; 77; 84; 11; 71; 35; 72; 28; 76; 82; 88; 32;
21; 20; 91; 62; 29|]
// not tail recursive. answer = 488
let N = X.Length
let mutable count = 0
let swap (A:int[]) a b =
let tmp = A.[a]
A.[a] <- A.[b]
A.[b] <- tmp
A
let rec quicksortNT (A:int[]) =
let L = A.Length
match L with
| 1 -> A
| 2 -> count <- count + 1
if (A.[0]<A.[1]) then A
else [|A.[1];A.[0]|]
| x -> let p = x
let pval = A.[p-1]
let A = swap A 0 (p-1)
let mutable i = 1
for j in 1 .. (x-1) do
if (A.[j]<pval) then let A = swap A i j
i <- i+1
// end of for loop
// putting back pivot at its right place
let A = swap A 0 (i-1)
let l1 = i-1
let l2 = x-i
if (l1=0) then
let A = Array.append [|A.[0]|] (quicksortNT A.[1..p-1])
count <- count + (l2-1)
A
elif (l2=0) then
let A = Array.append (quicksortNT A.[0..p-2]) [|A.[p-1]|]
count <- count + (l2-1)
A
else
let A = Array.append ( Array.append (quicksortNT A.[0..(i-2)]) [|A.[i-1]|] ) (quicksortNT A.[i..p-1])
count <- count + (l1-1)+(l2-1)
A
let Y = quicksortNT X
for i in 1..N do printfn "%d" Y.[i-1]
printfn "count = %d" count
Console.ReadKey() |> ignore
Thank you very much for your help
As I said in my comment: you do inplace-swapping so it makes no sense to recreate and return arrays.
But as you ask about tail-recursive solutions look at this version using lists and continuation-passing-style to make the algorithm tail-recursive:
let quicksort values =
let rec qsort xs cont =
match xs with
| [] -> cont xs
| (x::xs) ->
let lower = List.filter (fun y -> y <= x) xs
let upper = List.filter (fun y -> y > x) xs
qsort lower (fun lowerSorted ->
qsort upper (fun upperSorted -> cont (lowerSorted # x :: upperSorted)))
qsort values id
remarks:
you can think of it like this:
first partition the input into upper and lower parts
then start with sorting (recursively) the lower part, when you are done with this continue by...
... take lowerSorted and sort the upper part as well and continue with ...
... take both sorted parts, join them and pass them to the outer continuation
the outermost continuation should of course just be the id function
some will argue that this is not quicksort as it does not sort inplace!
maybe it's hard to see but it's tail-recursive as the very last call is to qsort and it's result will be the result of the current call
I used List because the pattern-matching is so much nicer - but you can adopt this to your version with arrays as well
in those cases (as here) where you have multiple recursive calls I always find cont-passing solutions to be easier to write and more natural - but accumulators could be used as well (but it will get messy as you need to pass where you are too)
this will not take less memory than the version without the cont-passing at all - it just will be placed on the heap instead of the stack (you usually have way more heap available ;) ) - so it's a bit like cheating
that's why the imperative algorithm is still way better performance-wise - so a usual compromise is to (for example) copy the array, use the inplace-algorithm on the copy and then return the copy - this way the algorithm behaves as if it's pure on the outside
The whole point to quicksort's swapping partition procedure is that it can mutate the same array; you just pass it the low and the high index of the array's range it has to process.
So make a nested function and pass it just the 2 indices. To make it tail recursive, add the third parameter, list-of-ranges-to-process; when that becomes empty, you're done. Wikibook says you mutate arrays with A.[i] <- A.[j].
A nested function can access its parent function's argument directly, because it is in scope. So, make swap nested too:
let rec quicksort (A:int[]) =
let swap a b =
let tmp = A.[a]
A.[a] <- A.[b]
A.[b] <- tmp
let todo = ... (* empty list *)
let rec partition low high =
.... (* run the swapping loop,
find the two new pairs of indices,
put one into TODO and call *)
partition new_low new_high
let L = A.Length
match L with
| 1 -> (* do nothing A *)
| 2 -> count <- count + 1
if (A.[0]<A.[1]) then (* do nothing A *)
else (* [|A.[1];A.[0]|] *) swap 1 0
| x -> ....
partition 0 L
So partition will be tail recursive, working inside the environment set up for it by quicksort.
(disclaimer: I don't know F# and have never used it, but I know Haskell and Scheme, to some degree).

How to find index of an Array element in OCaml

I am trying to find the index of an integer array element in ocaml. How to do this recursively.
Example code:let a = [|2; 3; 10|];;
suppose I want to return the index of 3 in the array a. Any help appreciated. I am new to OCaml programming
type opt = Some of int | None;;
let find a i =
let rec find a i n =
if a.(n)=i then Some n
else find a i (n+1)
in
try
find a i 0
with _ -> None
;;
Test
# find a 3;;
- : int option = Some 1
# find [||] 3;;
- : int option = None
# find a 12;;
- : int option = None
You check each of the elements recursively using an index
let rec find a x n =
if a.(n) = x then n
else find a x (n+1);;
find a x 0;;
that will raise an exception (when n is bigger than the length of the array) in case the element is not part of the array.
let f xs x =
let i = ref (-1) in
let () = Array.iteri (fun n elt -> if x = elt then i := n else ()) xs in
!i
The return value will be -1 if the element is not in the list.

OCaml count the negatives

I'm really stuck on how to go about this I am asked to count the number of negatives within the list, I would have submitted the assignment with:
let nneg = [4; 9; -5; 0; -5; 1];;
List.filter nneg (fun -> (-))
List.filter nneg (fun x -> x < 0)
but it's not an int list -> int but instead an int list
so I started this but I can't figure it out for the life of me how to pattern match it:
let rec rev nneg =
match nneg with
| [] -> 0
| head::tail -> (filter tail < 0) head;;
You don't want to filter the list. You want to fold it to an int. Also the call has wrong arguments.
# List.filter;;
- : ('a -> bool) -> 'a list -> 'a list = <fun>
So filter is a function that takes a function that returns bool and a list. Filter returns filtered list. Example usage of filter:
# List.filter (fun x -> x > 0) [1;2;3;-3];;
- : int list = [1; 2; 3]
Since this is an assignment I'll just give you a hint. Have a look at fold function here. Obviously, you can solve it by filtering all elements greater or equal 0 and then counting them, but that requires two iterations.

OCaml non decreasing list without List.function

Update: I can't use any List.function stuff.
I'm new to OCaml and I'm learning this course in which I'm supposed to calculate a list of non decreasing values from a list of values.
So for e.g. I have a list [1; 2; 3; 1; 2; 7; 6]
So function mono that takes in a list returns the following:
# mono [1; 2; 3; 1; 2; 7; 6];;
- : int list = [1; 2; 3; 7]
I do the following:
let rec calculateCheck value lst = (
match lst with
[] -> true
| x :: xs -> (
if (value < x) then
false
else
calculateCheck value xs
)
);;
let rec reverse_list lst = (
match lst with
[] -> []
| x :: xs -> (
reverse_list xs # [x]
)
);;
let shouldReverse = ref 1;;
let cancelReverse somelist lst = (
shouldReverse := 0;
reverse_list lst
);;
let rec mono lst = (
let somelist = ref lst in
if (!shouldReverse = 1) then
somelist := cancelReverse somelist lst
else
somelist := lst;
match !somelist with
[] -> []
| x :: xs -> (
if (calculateCheck x xs) then
[x] # mono xs
else
[] # mono xs
);
);;
Problem?
This only works once because of shouldReverse.
I cannot reverse the value; mono list should return non decreasing list.
Question?
Any easy way to do this?
Specifically how to get a subset of the list. For e.g. for [1; 2; 3; 5; 6], I want [1; 2; 3] as an output for 5 so that I can solve this issue recursively. The other thing, is you can have a list as [1; 2; 3; 5; 6; 5]:: so for the second 5, the output should be [1; 2; 3; 5; 6].
Any ideas?
Thanks
A good way to approach this kind of problem is to force yourself to
formulate what you're looking for formally, in a mathematically
correct way. With some training, this will usually get you
a description that is close to the final program you will write.
We are trying to define a function incr li that contains the
a strictly increasing subsequence of li. As Jeffrey Scoffield asked,
you may be looking for the
longest
such subsequence: this is an interesting and non-trivial algorithmic
problem that is well-studied, but given that you're a beginner
I suppose your teacher is asking for something simpler. Here is my
suggestion of a simpler specification: you are looking for all the
elements that are greater than all the elements before them in the
list.
A good way to produce mathematical definitions that are easy to turn
into algorithms is reasoning by induction: define a property on
natural numbers P(n) in terms of the predecessor P(n-1), or define
a property on a given list in terms of this property on a list of one
less element. Consider you want to define incr [x1; x2; x3; x4]. You
may express it either in terms of incr [x1; x2; x3] and x4, or in
terms of x1 and incr [x2; x3; x4].
incr [x1;x2;x3;x4] is incr[x1;x2;x3], plus x4 if it is bigger
than all the elements before it in the list, or, equivalently, the
biggest element of incr[x1;x2;x3]
incr [x1;x2;x3;x4] is incr[x2;x3;x4] where all the elements
smaller than x1 have been removed (they're not bigger than all
elements before them), and x1 added
These two precise definitions can of course be generalized to lists of
any length, and they give two different ways to write incr.
(* `incr1` defines `incr [x1;x2;x3;x4]` from `incr [x1;x2;x3]`,
keeping as intermediate values `subli` that corresponds to
`incr [x1;x2;x3]` in reverse order, and `biggest` the biggest
value encountered so far. *)
let incr1 li =
let rec incr subli biggest = function
| [] -> List.rev subli
| h::t ->
if h > biggest
then incr (h::subli) h t
else incr subli biggest t
in
match li with
| [] -> []
| h::t -> incr [h] h t
(* `incr2` defines `incr [x1;x2;x3;x4]` from `incr [x2;x3;x4]`; it
needs no additional parameter as this is just a recursive call on
the tail of the input list. *)
let rec incr2 = function
| [] -> []
| h::t ->
(* to go from `incr [x2;x3;x4]` to `incr [x1;x2;x3;x4]`, one
must remove all the elements of `incr [x2;x3;x4]` that are
smaller than `x1`, then add `x1` to it *)
let rec remove = function
| [] -> []
| h'::t ->
if h >= h' then remove t
else h'::t
in h :: remove (incr2 t)

Resources