reverse recursion in F# - recursion

(I am not sure about that whether reverse recursion is a correct name..)
I'd like to define a recursive function with initial value at k=n and terminate at k = 0
So I tried to write it in this way(here n = 10):
let rec f k =
match k with
|_ when k > 10 -> 0
| 10 -> 1
|_ -> (f n+1)-1
and the VS crashed. Could anyone help me?
dividing line------------------
I think my question is a little like this:
Consider a sequence with
a(10) = 1
a(k) = [a(k+1)*a(k+1)] + 1
a(k) = 0 if (k < 0 or k > 10)
How could I implement it in the F# ?

let rec f k =
match k with
|_ when k > 10 || k < 0 -> 0
| 10 -> 1
|_ -> f (k+1) * f (k+1) + 1

Related

Why the same function prints different output?

I have defined the following module to implement a matrix type:
module MatrixImplementation: MatrixADT.MatrixInterface =
struct
type 'a matrix = {n: int; m: int; c: 'a array array};;
let zeroes n m = {n= n; m= m; c= Array.make_matrix n m 0};;
let identity n =
let m = zeroes n n
in for i = 0 to (n-1) do
m.c.(i).(i) <- 1
done;
(m);
;;
let init n =
let m = zeroes n n
in for i = 0 to (n-1)do
for j = 0 to (n-1) do
m.c.(i).(j) <- (n-1) * i + j;
done;
done;
(m);
;;
(* . . . *)
let rec print_row rl =
match rl with
| [] -> print_string("");
| v::cl -> Format.printf "%2d " v; print_row cl;
;;
let rec print_matrix m =
match Array.to_list m.c with
| [] -> print_string("");
| r::rl ->
print_string "[ ";
print_row (Array.to_list r);
print_string "]\n";
print_matrix {n= ((m.n)-1); m= (m.m); c= Array.of_list rl};
;;
end;;
However when I declare matrices using the module functions (zeroes, identity, init) and try to print them, only part of the lines that compose them are formatted, the first lines are not correctly formatted.
For instance i tried with:
let empty = zeroes 3 5;;
let id = identity 4;;
let mat = init 5;;
print_matrix mat;;
print_matrix empty;;
print_matrix id;;
And I got it as a result:
[ ]
[ ]
[ ]
[ ]
[ ]
[ 0 1 2 3 4 4 5 6 7 8 8 9 10 11 12 12 13 14 15 16 16 17 18 19 20 0 0 0 0 0 ]
[ 0 0 0 0 0 ]
[ 0 0 0 0 0 ]
[ 1 0 0 0 ]
[ 0 1 0 0 ]
[ 0 0 1 0 ]
[ 0 0 0 1 ]
Stripping your code of unnecessary ; and ;; tokens, we can also implement your print_matrix function imperatively. Given that you're using arrays, this simply makes more sense.
Converting from arrays to lists and then back so that you can use recursion and pattern matching is both inefficient and makes your code more difficult to understand.
module MatrixImplementation =
struct
type 'a matrix = {n : int; m : int; c : 'a array array}
let zeroes n m = {n = n; m = m; c = Array.make_matrix n m 0}
let identity n =
let m = zeroes n n in
for i = 0 to (n-1) do
m.c.(i).(i) <- 1
done;
m
let init n =
let m = zeroes n n in
for i = 0 to (n-1) do
for j = 0 to (n-1) do
m.c.(i).(j) <- (n-1) * i + j
done;
done;
m
let print_matrix {n; m; c} =
for i = 0 to n - 1 do
print_string "[";
for j = 0 to m - 1 do
Printf.printf " %d " c.(i).(j)
done;
print_string "]\n"
done
end
utop # MatrixImplementation.(init 3 |> print_matrix);;
[ 0 1 2 ]
[ 2 3 4 ]
[ 4 5 6 ]
- : unit = ()
A note: print_string "" effectively does nothing. If you need to actually do nothing, you can simply return () (unit).
Note also that in print_matrix I've used pattern matching right in the function arguments (let print_matrix {n; m; c} =) to save myself some time. This could have been written as:
let print_matrix m =
for i = 0 to m.n - 1 do
print_string "[";
for j = 0 to m.m - 1 do
Printf.printf " %d " m.c.(i).(j)
done;
print_string "]\n"
done
We could take advantage of the Array.iter function.
let print_matrix {n; m; c} =
Array.(
let print_row arr =
print_string "[";
arr |> iter (Printf.printf " %d ");
print_string "]\n"
in
c |> iter print_row
)
If we consider your original approach, the following will fix it.
let rec print_row rl =
List.iter (Printf.printf " %2d ") rl
Reviewing the code of my module and its incorrect behavior, the problem is not the way the print functions are defined (leaving out the tricks suggested by #Chris in his answer), but the module used: the Format module should be used to make more complex printouts (API reference), the formatting error is probably due to the arguments of the fmt string; for simpler printing, the Printf module and its printf function (same arguments) are more suitable.
Therefore a possible change to the printing functions is as follows:
let rec print_row = function
| [] -> ()
| c::cl -> Printf.printf "%2d " c; print_row cl;
and print_matrix m =
match m.c with
| [] -> ()
| rows ->
for i= 0 to (List.length rows)-1 do
print_string("[ ");
print_row (List.nth rows i);
print_string("]\n");
done;
;;
(In this case the field c (content) of type definition matrix is int list list to avoid conversions)

Is there any way to optimize this function and make it faster?

is there a way to optimize this? It is taking way too long to run
let counter2 = ref 0
let rec s2 num =
counter2 := !counter2 + 1;
match num with
| 0 -> 1
| 1 -> 2
| _ -> (((((6*num)-3) * (s2 (num-1))) / (num+1))) - (((num-2)* (s2 (num-2))/(num+1)))
Here is the highly recursive definition of the Fibonacci sequence:
let rec fib n =
if n < 2 then n
else fib (n - 2) + fib (n - 1)
Here is the not so recursive definition of the Fibonacci sequence.
let nfib n =
let rec helper pprev prev i =
if i = n then
pprev + prev
else
helper prev (pprev + prev) (i + 1)
in
if n < 2 then n
else helper 0 1 2
Here is a function for timing things:
let time f x =
let st = Unix.gettimeofday () in
let res = f x in
Printf.printf "%f seconds\n" (Unix.gettimeofday () -. st);
res
Here are times for the fib and nfib functions:
# time fib 42;;
7.694294 seconds
- : int = 267914296
# time nfib 42;;
0.000002 seconds
- : int = 267914296

Tail-recursive solution to the coin change problem

I am trying to solve the coin change problem with tail recursion. The recursive solutions I come across are usually something like this
let rec combinations (amount:int) (coins:list<int>) =
if amount = 0 then
1
elif coins.IsEmpty || amount < 0 then
0
else
combinations (amount - coins.Head) coins + combinations amount coins.Tail
clearly inefficient and non tail recursive. I tried to make the solution tail recursive myself:
let combinationsTail (amount:int) (coins:list<int>) : int =
let rec go (amount:int) (sum:int) (coins:list<int>) =
match amount,sum ,coins with
| _,_, [] -> 0
| n,s,_ when n = 0 -> s
| n,_,cs when n < 0 || cs.IsEmpty -> 0
| n,s,h::t -> go (n - h) (n + s) t
go amount 0 coins
But it doesn't work. Does anyone know how to implement a tail recursive solution to this problem? is it even possible?
For achieving tail-recursiveness, you probably want to look into continuation-passing style. Here's an example applied to the Fibonacci sequence, which you could translate verbatim to the coins change problem, since both problems are dealing with aggregation of a recursive tree structure.
It's not the last word on efficiency.
let cc amount coins =
let rec aux k = function
| amount, _ when amount = 0 -> k 1
| amount, _ when amount < 0 -> k 0
| _, [] -> k 0
| amount, hd::tl ->
let k' x =
let k'' y = k (x + y)
aux k'' (amount - hd, hd::tl)
aux k' (amount, tl)
aux id (amount, coins)

Reversing an int in OCaml

I'm teaching myself OCaml, and the main resources I'm using for practice are some problem sets Cornell has made available from their 3110 class. One of the problems is to write a function to reverse an int (i.e: 1234 -> 4321, -1234 -> -4321, 2 -> 2, -10 -> -1 etc).
I have a working solution, but I'm concerned that it isn't exactly idiomatic OCaml:
let rev_int (i : int) : int =
let rec power cnt value =
if value / 10 = 0 then cnt
else power (10 * cnt) (value/10) in
let rec aux pow temp value =
if value <> 0 then aux (pow/10) (temp + (value mod 10 * pow)) (value / 10)
else temp in
aux (power 1 i) 0 i
It works properly in all cases as far as I can tell, but it just seems seriously "un-OCaml" to me, particularly because I'm running through the length of the int twice with two inner-functions. So I'm just wondering whether there's a more "OCaml" way to do this.
I would say, that the following is idiomatic enough.
(* [rev x] returns such value [y] that its decimal representation
is a reverse of decimal representation of [x], e.g.,
[rev 12345 = 54321] *)
let rev n =
let rec loop acc n =
if n = 0 then acc
else loop (acc * 10 + n mod 10) (n / 10) in
loop 0 n
But as Jeffrey said in a comment, your solution is quite idiomatic, although not the nicest one.
Btw, my own style, would be to write like this:
let rev n =
let rec loop acc = function
| 0 -> acc
| n -> loop (acc * 10 + n mod 10) (n / 10) in
loop 0 n
As I prefer pattern matching to if/then/else. But this is a matter of mine personal taste.
I can propose you some way of doing it:
let decompose_int i =
let r = i / 10 in
i - (r * 10) , r
This function allows me to decompose the integer as if I had a list.
For instance 1234 is decomposed into 4 and 123.
Then we reverse it.
let rec rev_int i = match decompose_int i with
| x , 0 -> 10 , x
| h , t ->
let (m,r) = rev_int t in
(10 * m, h * m + r)
The idea here is to return 10, 100, 1000... and so on to know where to place the last digit.
What I wanted to do here is to treat them as I would treat lists, decompose_int being a List.hd and List.tl equivalent.

Ocaml nested if without else

Is it possible to have nested if without else statements. I wrote the following useless program to demonstrate nested ifs. How do I fix this so it's correct in terms of syntax. lines 5 and 6 gives errors.
let rec move_helper b sz r = match b with
[] -> r
|(h :: t) ->
if h = 0 then
if h - 1 = sz then h - 1 ::r
if h + 1 = sz then h + 1 ::r
else move_helper t sz r
;;
let move_pos b =
move_helper b 3 r
;;
let g = move_pos [0;8;7;6;5;4;3;2;1]
You can't have if without else unless the result of the expression is of type unit. This isn't the case for your code, so it's not possible.
Here's an example where the result is unit:
let f x =
if x land 1 <> 0 then print_string "1";
if x land 2 <> 0 then print_string "2";
if x land 4 <> 0 then print_string "4"
You must understand that if ... then is an expression like any other. If no else is present, it must be understood as if ... then ... else () and thus has type unit. To emphasize the fact that it is an expression, suppose you have two functions f and g of type, say, int → int. You can write
(if test then f else g) 1
You must also understand that x :: r does not change r at all, it constructs a new list putting x in front of r (the tail of this list is shared with the list r). In your case, the logic is not clear: what is the result when h=0 but the two if fail?
let rec move_helper b sz r = match b with
| [] -> r
| h :: t ->
if h = 0 then
if h - 1 = sz then (h - 1) :: r
else if h + 1 = sz then (h + 1) :: r
else (* What do you want to return here? *)
else move_helper t sz r
When you have a if, always put an else. Because when you don't put an else, Java will not know if the case is true or false.

Resources