Call us +96895672917 | +917736882141

Project Description

Get Quick Ocaml Expert help / OCAML assignment help

Ocaml Programming Question 1 and Question 2

ocaml experts

(* Question 1 *)

let rec find_map (f : ‘a -> ‘b option) (l : ‘a list) : ‘b option =
match l with
| [] -> None
| hd :: lss ->
match f hd with
| None -> find_map f lss
| Some v -> Some v
;;

let partition (p : ‘a -> bool) (l : ‘a list) : (‘a list * ‘a list) =
let splitter (yes, no) e = if p e then (e::yes, no) else (yes, e::no) in
let yess, noo = List.fold_left splitter ([], []) l in
(List.rev yess, List.rev noo)
;;

.

(* Question 2 *)

exception WrongPassword
exception AccountLocked

type password = string
type address = string
type masterpass = password

type pass_manager = {
save : masterpass -> address -> password -> unit;
get_force : masterpass -> address -> password option;
get : masterpass -> address -> password option;
update_master : masterpass -> masterpass -> unit;
count_ops : masterpass -> int;
} ;;

let encrypt masterpass pw = masterpass ^ “,” ^ pw
let decrypt masterpass pw = List.hd (List.tl (String.split_on_char ‘,’ pw))

let make_manager (masterpass : masterpass) : pass_manager =
let ref_mp : masterpass ref = ref masterpass in
let ref_wrong_pw : int ref = ref 0 in
let ref_successful_call : int ref = ref 0 in
let ref_list : (address * password) list ref = ref [] in

(* Helper functions *)

let check_mp (mp : masterpass) = mp = !ref_mp in
let is_not_locked = (!ref_wrong_pw) <> 3 in
let report_wrong_call () = ref_wrong_pw := !ref_wrong_pw + 1 in

(* Manager functions *)
let save’ (mp : masterpass) addr pw : unit =
if is_not_locked then
if check_mp mp then
ref_list := (addr, pw)::!ref_list
else begin
report_wrong_call ();
raise WrongPassword
end
else
raise AccountLocked
in

let get_force’ mp addr =
find_map (fun (adr, pw) ->
if adr = addr then Some (decrypt mp pw)
else None) ref_list.contents
in

let get’ mp addr =
if is_not_locked then
if check_mp mp
then
get_force’ mp addr
else begin
report_wrong_call ();
raise WrongPassword
end
else
raise AccountLocked
in

let update_master’ old_mp new_mp : unit =
if is_not_locked then
if check_mp old_mp
then
let _ = List.map
(fun (addr, lp) ->
(addr, encrypt new_mp (decrypt old_mp lp))
) ref_list.contents
in ref_mp := new_mp
else begin
report_wrong_call ();
raise WrongPassword
end
else
raise AccountLocked
in

let count_ops’ mp : int =
if is_not_locked then
if check_mp mp
then begin
ref_successful_call := !ref_successful_call + 1;
!ref_successful_call
end
else begin
report_wrong_call ();
raise WrongPassword
end
else
raise AccountLocked
in
(* Brand-new record *)
let account = {
save = save’;
get_force = get_force’;
get = get’;
update_master = update_master’;
count_ops = count_ops’;
} in account
;;

(* Question 3 *)

let rec catalan n =
if n = 0 then 1
else
let rec aux i n acc =
if i > n then acc
else aux (i + 1) n (acc + catalan i * catalan (n – i))
in
aux 0 (n-1) 0
;;

(* Counting values at same time *)
let catalan_count (n : int) : (int * int) =
let count_rec_calls : int ref = ref 0 in
let rec inner_catalan nn =
if nn = 0 then
begin
incr count_rec_calls;
1
end
else
let rec aux i ni acc =
if i > ni then acc
else
aux (i + 1) ni (acc + inner_catalan i * inner_catalan (ni – i))
in
begin
incr count_rec_calls;
aux 0 (nn-1) 0
end
in inner_catalan n, !count_rec_calls
;;

type stats = {
entries : int ref;
lkp : int ref
} ;;

(* Memoization function *)
let memoize (f : (‘a -> ‘b) -> ‘a -> ‘b) (stats : stats) : ‘a -> ‘b =
let hash = Hashtbl.create 1000 in
let rec f’ x =
match Hashtbl.find_opt hash x with
| Some b -> stats.lkp := !(stats.lkp) + 1; b
| None ->
let value = f f’ x in
begin
Hashtbl.add hash x value;
stats.entries := !(stats.entries) + 1;
value
end
in f’
;;

(* Version of catalan that can be memoized *)
let memo_cat (recf : int -> int) (n : int) : int =
if n = 0 then 1
else
let rec aux i n acc =
if i > n then acc
else aux (i + 1) n (acc + recf i * recf (n – i))
in aux 0 (n-1) 0
;;

let catalan_m (n : int) : int * stats =
let state = { entries = ref 0; lkp = ref 0} in
((memoize memo_cat state) n , state)
;;

Project Details

  • Date November 24, 2021
  • Tags Functional programming, Ocaml programming help