0
votes

I have a recursive function and I want the rewriting in the Mémoïsant

My recursive function:

let rec sum_cube l =
    match l with
    | [] -> 0
    | x :: s -> (x * x * x) + sum_cube s

and I tried with this:

let memo = Hashtbl.create 17 
let rec sum_cub_memo l =
    try 
      Hashtbl.find memo l 
    with Not_found -> 
      let fn = function
        | [] -> 0
        | x::s -> (x * x * x ) sum_cub_memo s
      in
        Hashtbl.add memo l fn 

fn ;;

I have an error:

This expression has type int list -> int but an expression was expected of type int list!!

2
Which expression?melpomene
Ah. Take a closer look at fn. What is it? How are you using it?melpomene
@melpomene Hashtbl.add memo l fnuser6332149

2 Answers

0
votes

You should memoize not the function, but the result of the function, e.g., using your definition of sum_cube:

let sum_cube_memo xs = 
  try Hashtbl.find memo xs with Not_found ->
    let res = sum_cube xs in
    Hashtbl.add memo xs res;
    res

This will work, however there is a caveat. You're using a list of integers as a key. That means, that first the key is transformed to its hash (basically O(n), and will take basically the same amount of time as computing the power of three), second, if there is a hash collision, then every list in the bucket will be compared with the argument list. As a result, your memoized function has the same complexity as your non-memoized function, it has worse performance, and also consumes unbound amount of memory. Is it worthwhile?

0
votes

sum_cube without memorization.

let sum_cube l =
  let cube x =x*x*x in
  List.fold_left ( fun acc x -> acc+cube x) 0 l

sum_cube with memorization and trace.

let sum_cube l =
  let memo = Hashtbl.create 17 in
  let cube_memo x =
    try
      let xcube= Hashtbl.find memo x in
      Printf.printf "find %d -> %d\n" x xcube;
      xcube
    with Not_found -> 
      let xcube=x*x*x in
      Printf.printf "add  %d -> %d\n" x xcube;
      Hashtbl.add memo x xcube;
      xcube
  in
  List.fold_left ( fun acc x -> acc+cube_memo x) 0 l

Test :

#  sum_cube [4;4;2;3;4;2];;
add  4 -> 64
find 4 -> 64
add  2 -> 8
add  3 -> 27
find 4 -> 64
find 2 -> 8
- : int = 235