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.
Related
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.
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).
As a tutoring exercise I implemented the Knights Tour algorithm in CS and worked fine, after trying to port it to F# I cannot go past the part where I aggregate the resulting sequences of the Knight's path to return to the caller.
The code is this:
let offsets = [|(-2,-1);(-2,1);(-1,-2);(-1,2);(1,-2);(1,2);(2,-1);(2,1)|];
let squareToPair sqr =
(sqr % 8, sqr / 8)
let pairToSquare (col, row) =
row * 8 + col
// Memoizing function taken from Don Syme (http://blogs.msdn.com/b/dsyme/archive/2007/05/31/a-sample-of-the-memoization-pattern-in-f.aspx)
let memoize f =
let cache = ref Map.empty
fun x ->
match (!cache).TryFind(x) with
| Some res -> res
| None ->
let res = f x
cache := (!cache).Add(x,res)
res
let getNextMoves square =
let (col, row) = squareToPair square
offsets
|> Seq.map (fun (colOff, rowOff) -> (col + colOff, row + rowOff))
|> Seq.filter (fun (c, r) -> c >= 0 && c < 8 && r >= 0 && r < 8) // make sure we don't include squares out of the board
|> Seq.map (fun (c, r) -> pairToSquare (c, r))
let getNextMovesMemoized = memoize getNextMoves
let squareToBoard square =
1L <<< square
let squareToBoardMemoized = memoize squareToBoard
let getValidMoves square board =
getNextMovesMemoized square
|> Seq.filter (fun sqr -> ((squareToBoardMemoized sqr) &&& board) = 0L)
// gets all valid moves from a particular square and board state sorted by moves which have less next possible moves
let getValidMovesSorted square board =
getValidMoves square board
|> Seq.sortBy (fun sqr -> (getValidMoves sqr board) |> Seq.length )
let nextMoves = getValidMovesSorted
let sqrToBoard = squareToBoardMemoized
let findPath square =
let board = sqrToBoard square
let rec findPathRec brd sqr sequence = seq {
match brd with
| -1L -> yield sequence
| _ -> for m in nextMoves sqr do yield! findPathRec (brd ||| (sqrToBoard m)) m m::sequence
}
findPathRec board square [square]
let solution = findPath ((4,4) |> pairToSquare) |> Seq.take 1
I am getting the following error:
The type '(int64 -> seq<int>)' is not a type whose values can be enumerated with this syntax, i.e. is not compatible with either seq<_>, IEnumerable<_> or IEnumerable and does not have a GetEnumerator method (using external F# compiler)
I could probably be misunderstanding how this work, but I would expect the results of nextMoves to be seq<_>. Is there a better way of doing this? Am I missing something? Any recommended patterns?
Thanks in advance!
So the problem is that nextMoves has type
val nextMoves : (int -> int64 -> seq<int>)
because it is identical to getValidMovesSorted. You need to supply the board argument
nextMoves is just getValidMovesSorted which takes two arguments (square and board) - now in findPath you only provided one and I guess you wanted to write this
nextMoves sqr board
but then there are more issues in the rest of the code and it's really hard to figure out what you are trying to do
I think you wanted to do something like this:
let findPath square =
let board = sqrToBoard square
let rec findPathRec brd sqr (sequence : int list) =
match brd with
| -1L -> sequence
| _ ->
[
for m in nextMoves sqr board do
yield! findPathRec (brd ||| (sqrToBoard m)) m (m::sequence)
]
this will compile (but will result in an stack-overflow exception)
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)
I'm trying to write a function that accepts an int n and returns a list that runs down from n to 0.
This is what I have
let rec downFrom n =
let m = n+1 in
if m = 0 then
[]
else
(m-1) :: downFrom (m - 1);;
The function compiles ok but when I test it with any int it gives me the error
Stack overflow during evaluation (looping recursion?).
I know it's the local varible that gets in the way but I don't know another way to declare it. Thank you!!!
First, the real thing wrong with your program is that you have an infinite loop. Why, because your inductive base case is 0, but you always stay at n! This is because you recurse on m - 1 which is really n + 1 - 1
I'm surprised as to why this compiles, because it doesn't include the rec keyword, which is necessary on recursive functions. To avoid stack overflows in OCaml, you generally switch to a tail recursive style, such as follows:
let downFrom n =
let rec h n acc =
if n = 0 then List.rev acc else h (n-1) (n::acc)
in
h n []
Someone suggested the following edit:
let downFrom n =
let rec h m acc =
if m > n then acc else h (m + 1) (m::acc)
in
h 0 [];
This saves a call to List.rev, I agree.
The key with recursion is that the recursive call has to be a smaller version of the problem. Your recursive call doesn't create a smaller version of the problem. It just repeats the same problem.
You can try with a filtering parameter
syntax:
let f = function
p1 -> expr1
| p2 -> expr2
| p3 -> ...;;
let rec n_to_one =function
0->[]
|n->n::n_to_one (n-1);;
# n_to_one 3;;
- : int list = [3; 2; 1]