Le problème du Duc de Toscane simulé avec CAML. On fabrique nos outils...
OCaml
(* vecteur aléatoire de n entiers entre min et max *) let vec_alea (min: int) (max: int) (taille: int): int list = let rec aux_alea (size: int) (acc: int list): int list = if size = 0 then acc else aux_alea (size - 1) ((min + Random.int (max - min + 1)) :: acc) in aux_alea taille [];; (* sommes des éléments d'une liste d'entiers *) let somme (liste : int list): int = List.fold_left (+) 0 liste;; (* une liste d'expériences aléatoires *) let simul_exp (exp: unit -> 'issue) (occ: int): 'issue list = let rec aux_exp = fun n acc -> if n = occ then acc else aux_exp (n + 1) ((exp ()) :: acc) in aux_exp 0 [];; (* simulations du lancer de trois dés : X = somme des faces *) let toscane ((): unit): int = somme (vec_alea 1 6 3);; (* pour clarifier : on définit un type polymorphe pour les dictionnaire avec un constructeur d'arité 1 *) type ('cle,'valeur) dictionnaire = Dict of ('cle * 'valeur) list;; let list_of_dic (d: ('cle,'valeur) dictionnaire): ('cle * 'valeur) list = match d with Dict(li) -> li;; (* renvoie la liste des couples (élément, fréquence en pourcentage) *) let compte (liste: 'issue list) : ('issue,float) dictionnaire = let effectif_total = float_of_int (List.length liste) in let rec count (l: 'issue list) (accu: ('issue * float) list) : ('issue,float) dictionnaire = match l with | [] -> Dict(accu) |t :: q -> let c = List.partition (fun x -> x = t) l in count (snd c) ((t,100. *. (float_of_int (List.length (fst c))) /. effectif_total)::accu) in count liste [];; (* on entre l'expérience et le nb de simulations et on obtient le dictionnaire des fréquences en pourcentage *) let simul_dic (exp_alea: unit -> 'issue) (nb_exp: int): ('issue,float) dictionnaire = let li = list_of_dic (compte (simul_exp exp_alea nb_exp)) in Dict(List.sort compare li);; (* idem avec un joli affichage sous forme de chaîne de caractères *) let pretty_dic (ft: ('i -> 's, unit, string) format) (dic: ('a,float) dictionnaire): ('a , string) dictionnaire = Dict(List.map (fun cpl -> (fst cpl, Printf.sprintf ft (snd cpl) ^ " %")) (list_of_dic dic));; (* simule 100_000 expériences du Duc de Toscane *) simul_dic toscane 100_000;; pretty_dic "%.2f" (simul_dic toscane 100_000);;