module M = Map.Make(String)
let dict = M.singleton "a" "d" |> M.add "d" "c" |> M.add "c" "b"


(* caută repetat până la o valoare care nu mai e cheie, presupunând că există:
a -> d -> c -> b; eșuează prin depășire de stivă în caz de ciclu *)
let findlast dict =
  let rec find_inner sir = try find_inner (M.find sir dict)
                           with Not_found -> sir
  in find_inner

(* punctul fix al șirului x, f(x), f(f(x)) etc, presupunând că există *)
let fix f = 
  let rec _fix x = let y = f x in if y = x then y else _fix y
  in _fix

let rec sumcif n = if n < 10 then n else n mod 10 + sumcif (n / 10)

let sumfinal = fix sumcif        (* ajunge la o singură cifră *)

let t = sumfinal 1345675674  (* 48 -> 12 -> 3 *)

(* calculează repetat acc |> f n |> f (n-1) |> ... |> f 1
   ca și List_fold_right f [1; 2; ...; n] init fără a construi lista *)
let foldrange f =
  let rec foldr n acc = if (n <= 0) then acc else foldr (n-1) (f n acc)
  in foldr

(* dicționar cu chei întregi *)
module IM = Map.Make(struct type t = int let compare = compare end)

(* incrementează valoarea pentru cheia k în dict. m *)
let incfreq k m = let cnt = try IM.find k m
                            with Not_found -> 0
                  in IM.add k (cnt+1) m

(* frecvența valorilor f(k) pentru k = 1 .. n *)
let freq f n = foldrange (fun k -> f k |> incfreq) n IM.empty

(* frecvența pentru suma sumei sumei ... cifrelor, numere de la 1 la 1000 *)
let test = freq sumfinal 1000 |> IM.bindings         

This document was generated using caml2html