OCaml count the negatives - functional-programming

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.

Related

How can I create a type in order to accommodate the return value of my Ocaml function?

I am trying to implement a lazy fibonacci generator in Ocaml as shown below:
(* fib's helper *)
let rec fibhlpr n = if n == 0 then 0 else if n == 1 then 1 else fibhlpr (n-1) + fibhlpr (n-2);;
(* lazy fib? *)
let rec fib n = ((fibhlpr n), fun() -> fib (n+1));;
I am trying to return the result of fibhlpr (an int) and a function to retrieve the next value, but am not sure how. I think I have to create a new type in order to accommodate the two items I am returning, but I don't know what type fun() -> fib (n+1) returns. When messing around with the code, I received an error which informed me that
fun() -> fib (n+1) has type: int * (unit ->'a).
I am rather new to Ocaml and functional programming in general, so I don't know what this means. I tried creating a new type as follows:
type t = int * (unit -> 'a);;
However, I received the error: "Unbound type parameter 'a".
At this point I am truly stuck: how can I returns the two items that I want (the result of fibhlpr n and a function which returns the next value in the sequence) without causing an error? Thank you for any help.
If you want to define a lazy sequence, you can use the built-in sequence type
constructor Seq.t
let rec gen_fib a b () = Seq.Cons(a, gen_fib b (a+b))
let fib () = gen_fib 0 1 ()
This implementation also has the advantage that computing the n-th term of the sequence is O(n) rather than O(2^n).
If you want to keep using an infinite lazy type, it is also possible. However, you cannot use the recursive type expression
type t = int * (unit -> t)
without the -rectypes flag. And using -rectypes is generally ill-advised for beginners because it reduces the ability of type inference to identify programming errors.
It is thus better to simply use a recursive type definition as suggested by #G4143
type 'a infinite_sequence = { x:'a; next: unit -> 'a infinite_sequence }
let rec gen_fib a b () =
{ x = a; next = gen_fib b (a+b) }
let fib = gen_fib 0 1 ()
The correct type is
type t = int * (unit -> t)
You do not need a polymorphic 'a, because fibonacci only ever yields ints.
However, when you call the next function, you need to get the next value, but also a way to get the one after it, and so on and so on. You could call the function multiple times, but then it means that the function has mutable state, the above signature doesn't require that.
Try:
type 'a t = int * (unit -> 'a);
Your whole problems stems from this function:
let rec fib n = ((fibhlpr n), fun() -> fib (n+1))
I don't think the type system can define fib when it returns itself.. You need to create a new type which can construct a function to return.
I quickly tried this and it works:
type func = Func of (unit ->(int * func))
let rec fib n =
let c = ref 0 in
let rec f () =
if !c < n
then
(
c := !c + 1;
((fibhlpr !c), (Func f))
)
else
failwith "Done"
in
f
Following octachron's lead.. Here's a solution using Seq's unfold function.
let rec fibhlpr n =
if n == 0
then
0
else if n == 1
then
1
else
fibhlpr (n-1) + fibhlpr (n-2)
type func = Func of (unit -> (int * int * func))
let rec fib n =
(n, (fibhlpr n), Func(fun() -> fib (n+1)))
let seq =
fun x ->
Seq.unfold
(
fun e ->
let (c, d, Func f) = e in
if c > x
then
None
else
(
Some((c, d), f())
)
) (fib 0)
let () =
Seq.iter
(fun (c, d) -> Printf.printf "%d: %d\n" c d; (flush stdout)) (seq 30)
You started right saying your fib function returns an integer and a function:
type t = int * (unit -> 'a);;
But as the compiler says the 'a is not bound to anything. Your function also isn't polymorphic so that is has to return a type variable. The function you return is the fib function for the next number. Which also returns an integer and a function:
type t = int * (unit -> int * (unit -> 'a));;
But that second function again is the fib function for the next number.
type t = int * (unit -> int * (unit -> int * (unit -> 'a)))
And so on to infinity. Your type definition is actually recursive. The function you return as second half has the same type as the overall return type. You might try to write this as:
# type t = int * (unit -> t);;
Error: The type abbreviation t is cyclic
Recursive types are not allowed in ocaml unless the -rectypes option is used, which has some other side effects you should read about before using it.
A different way to break the cycle is to insert a Constructor into the cyclic type by making it a variant type:
# type t = Pair of int * (unit -> t)
let rec fibhlpr n = if n == 0 then 0 else if n == 1 then 1 else fibhlpr (n-1) + fibhlpr (n-2)
let rec fib n = Pair ((fibhlpr n), fun() -> fib (n+1));;
type t = Pair of int * (unit -> t)
val fibhlpr : int -> int = <fun>
val fib : int -> t = <fun>
Encapsulating the type recursion into a record type also works and might be the more common solution. Something like:
type t = { value : int; next : unit -> t; }
I also think you are missing the point of the exercise. Unless I'm mistaken the point of making it a generator is so that the function can compute the next fibonacci number from the two previous numbers, which you remember, instead of computing it recursively over and over.

Practicing on matrix - Ocaml

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

Average calculating of consecutive list elements in OCaml

I am trying to write a function in OCaml that will calculate the average of consecutive elements in a list. For example with [1; 2; 3; 4] it should output [1; 2; 3]. It should take (1 + 2) / 2 and give 1 then take (2 + 3) / 2 and give 2 and so on.
The code I wrote, however, only returns [1; 2]:
let rec average2 xs = match xs with
|[] -> []
|x :: [] -> [x]
|x :: x' :: xs -> if xs = [] then [(x + x') / 2] else [(x + x') / 2] # (average2 xs)
Can you please tell me how to fix this. Thank you.
When you're doing x :: y :: l in a match, you're effectively taking out the elements of the list permanently.
So if you want to do an operation on pairs of elements, you need to put one back in.
Example:
You have a list of [1;2;3;4]
You want to operate on 1 and 2, in your match it will interpret as:
1 :: 2 :: [3;4]
If you continue without adding an element in, the next statement would be:
3 :: 4 :: []
which is not what you want.
To correct this, in your recurice call you need to do (average2 (x'::xs) and not just (average2 xs) because xs is the rest of the list after taking the elements out.
OCaml allows to bind a pattern p to a variable v using p as v (alias patterns):
let rec average2 = function
| x :: (y :: _ as tail) -> (x + y) / 2 :: (average2 tail)
| _ -> []
Above, y :: _ as tail destructures a list named tail as a non-empty list headed by y and having an arbitrary tail _, the value of which we don't care about.
Note that I also simplified your function so that you don't check whether _ is empty or not: recursion handles this for you here.
Also, when you have zero or one element in the list, you should return an empty list.
# average2 [ 10; 20; 30; 40];;
- : int list = [15; 25; 35]

F# Iterate over N dimensions [duplicate]

I was given a puzzle as a present. It consists of 4 cubes, arranged side by side. The faces of each cube are one of four colours.
To solve the puzzle, the cubes must be orientated so that all four cubes' tops are different, all their fronts are different, all their backs are different and all their bottom's are different. The left and right sides do not matter.
My pseudo-code solution was:
Create a representation of each
cube.
Get all the possible orientations of
each cube (there are 24 for each).
Get all the possible combinations of
orientations of each cube.
Find the combination of orientations
that satisfies the solution.
I solved the puzzle using an implementation of that pseudo-code in F#, but am not satisifed with the way I did step 3:
let problemSpace =
seq { for c1 in cube1Orientations do
for c2 in cube2Orientations do
for c3 in cube3Orientations do
for c4 in cube4Orientations do
yield [c1; c2; c3; c4] }
The above code is very concrete, and only works out the cartesian product of four sequences of orientations. I started thinking about a way to write it for n sequences of orientations.
I came up with (all the code from now on should execute fine in F# interactive):
// Used to just print the contents of a list.
let print =
Seq.fold (fun s i -> s + i.ToString()) "" >> printfn "%s"
// Computes the product of two sequences - kind of; the 2nd argument is weird.
let product (seq1:'a seq) (seq2:'a seq seq) =
seq { for item1 in seq1 do
for item2 in seq2 do
yield item1 |> Seq.singleton |> Seq.append item2 }
The product function could be used like so...
seq { yield Seq.empty }
|> product [ 'a'; 'b'; 'c' ]
|> product [ 'd'; 'e'; 'f' ]
|> product [ 'h'; 'i'; 'j' ]
|> Seq.iter print
... which lead to ...
let productn (s:seq<#seq<'a>>) =
s |> Seq.fold (fun r s -> r |> product s) (seq { yield Seq.empty })
[ [ 'a'; 'b'; 'c' ]
[ 'd'; 'e'; 'f' ]
[ 'h'; 'i'; 'j' ] ]
|> productn
|> Seq.iter print
This is exactly the usage I want. productn has exactly the signature I want and works.
However, using product involves the nasty line seq { yield Seq.empty }, and it unintuitively takes:
A sequence of values (seq<'a>)
A sequence of sequences of values (seq<seq<'a>>)
The second argument doesn't seem correct.
That strange interface is hidden nicely by productn, but is still nagging me regardless.
Are there any nicer, more intuitive ways to generically compute the cartesian product of n sequences? Are there any built in functions (or combination of) that do this?
Use recursion: the cartesian product of n lists {L1..LN} is the collection of lists you get when you add each element in L1 to each sublist in the cartesian product of lists {L2..LN}.
let rec cart1 LL =
match LL with
| [] -> Seq.singleton []
| L::Ls -> seq {for x in L do for xs in cart1 Ls -> x::xs}
Example:
> cart1 [[1;2];[3;4;5];[6;7]] |> Seq.toList;;
val it : int list list =
[[1; 3; 6]; [1; 3; 7]; [1; 4; 6]; [1; 4; 7]; [1; 5; 6]; [1; 5; 7]; [2; 3; 6];
[2; 3; 7]; [2; 4; 6]; [2; 4; 7]; [2; 5; 6]; [2; 5; 7]]
The cartesian product of [1;2] [3;4;5] and [6;7] is the union of {1 appended to each list in cart [[3;4;5];[6;7]]} and {2 appended to each list in cart [[3;4;5];[6;7]]}. This is the second clause in the match statement.
Here's a solution 'a list list -> Seq<'a list> to calculate the Cartesian product of n lists, with lazy evaluation. I wrote it to be an F# analogue of Python's itertools.product
let product lists =
let folder list state =
state |> Seq.allPairs list |> Seq.map List.Cons
Seq.singleton List.empty |> List.foldBack folder lists
It's based on List.allPairs which was introduced in F# 4.0.
Here's a first try at a list version. I think it could be cleaned up a bit.
let rec cart nll =
let f0 n nll =
match nll with
| [] -> [[n]]
| _ -> List.map (fun nl->n::nl) nll
match nll with
| [] -> []
| h::t -> List.collect (fun n->f0 n (cart t)) h

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