Skip to content
Snippets Groups Projects
Commit 83c0be4f authored by COQUERY EMMANUEL's avatar COQUERY EMMANUEL
Browse files

seance 8 avril + correction tp7

parent bcfcb3ff
No related branches found
No related tags found
No related merge requests found
No preview for this file type
File added
No preview for this file type
tp/tp7.ml 0 → 100644
module Association = struct
(* Type pour représenter des dictionnaires (ou map ou association) dont la clé est une string *)
type 'a t = Vide | Noeud of string * 'a * 'a t * 'a t
(* Fonction pour chercher dans un dictionnaire. get d k renvoie None si k n'est pas une clé de d,
Some x si x est la valeur associée à k dans d. *)
let _test_data1 =
Noeud
( "b",
2,
Noeud ("a", 1, Vide, Vide),
Noeud ("c", 3, Vide, Noeud ("d", 4, Vide, Vide)) )
let rec get : 'a t -> string -> 'a option =
fun d k ->
match d with
| Vide -> None
| Noeud (k', v', fg, fd) ->
if k = k' then Some v' else if k < k' then get fg k else get fd k
;;
assert (Some 1 = get _test_data1 "a");;
assert (Some 4 = get _test_data1 "d")
(* Ajoute un couple clé/valeur dans un dictionnaire, si la clé est déjà dans le dictionnaire,
change en v la valeur qui sera renvoyée par get *)
let rec put : 'a t -> string -> 'a -> 'a t =
fun d k v ->
match d with
| Vide -> Noeud (k, v, Vide, Vide)
| Noeud (k', v', fg, fd) ->
if k = k' then Noeud (k, v, fg, fd)
else if k < k' then Noeud (k', v', put fg k v, fd)
else Noeud (k', v', fg, put fd k v)
;;
assert (Some 5 = get (put _test_data1 "e" 5) "e");;
assert (Some 4 = get (put _test_data1 "e" 5) "d")
(* Le dictionnaire vide *)
let empty : 'a t = Vide
(* Supprime les valeurs associées à la clé k dans le dictionnaire. *)
let rec delete : 'a t -> string -> 'a t =
(* suppose k1 < k2 *)
let rec fusionne d1 d2 =
match (d1, d2) with
| Vide, Vide -> Vide
| Vide, d | d, Vide -> d
| Noeud (k1, v1, fg1, fd1), Noeud (k2, v2, fg2, fd2) ->
Noeud (k1, v1, fg1, Noeud (k2, v2, fusionne fd1 fg2, fd2))
in
fun d k ->
match d with
| Vide -> Vide
| Noeud (k', v', fg, fd) ->
if k = k' then fusionne fg fd
else if k < k' then Noeud (k', v', delete fg k, fd)
else Noeud (k', v', fg, delete fd k)
;;
assert (None = get (delete _test_data1 "a") "a");;
assert (None = get (delete _test_data1 "d") "d");;
assert (Some 3 = get (delete _test_data1 "d") "c")
let rec fold : ('acc -> string -> 'a -> 'acc) -> 'acc -> 'a t -> 'acc =
fun f init d ->
match d with
| Vide -> init
| Noeud (k, v, fg, fd) -> fold f (f (fold f init fd) k v) fg
(* on utilise fold_right pour garder l'ordre, ce qui est important
pour au cas où une clé est plusieurs fois dans la liste *)
let to_list : 'a t -> (string * 'a) list =
fun d -> fold (fun acc k v -> (k, v) :: acc) [] d
end
module Usine = struct
type jour = Lundi | Mardi | Mercredi | Jeudi | Vendredi | Samedi | Dimanche
let string_of_jour (j : jour) =
match j with
| Lundi -> "lundi"
| Mardi -> "mardi"
| Mercredi -> "mercredi"
| Jeudi -> "jeudi"
| Vendredi -> "vendredi"
| Samedi -> "samedi"
| Dimanche -> "dimanche"
let jours_test_data =
[ Lundi; Mardi; Mercredi; Jeudi; Vendredi; Samedi; Dimanche ]
let string_test_data =
[ "lundi"; "mardi"; "mercredi"; "jeudi"; "vendredi"; "samedi"; "dimanche" ]
let _ =
List.combine jours_test_data string_test_data
|> List.iter (fun (j, s) -> assert (s = string_of_jour j))
let jour_opt_of_string (s : string) =
match s with
| "lundi" -> Some Lundi
| "mardi" -> Some Mardi
| "mercredi" -> Some Mercredi
| "jeudi" -> Some Jeudi
| "vendredi" -> Some Vendredi
| "samedi" -> Some Samedi
| "dimanche" -> Some Dimanche
| _ -> None
let _ =
List.combine jours_test_data string_test_data
|> List.iter (fun (j, s) -> assert (Some j = jour_opt_of_string s))
;;
assert (None = jour_opt_of_string "toto")
type configuration =
(string -> string option) * (string -> string -> int option)
let mk_configuration :
(string -> string option) ->
(string -> string -> int option) ->
configuration =
fun choix_jouet choix_nombre -> (choix_jouet, choix_nombre)
let get_jouet : configuration -> string -> string option = fst
let get_nb_jouets : configuration -> string -> string -> int option = snd
let toupie _lutin = Some "toupie"
let quanrante_deux _lutin _jouet = Some 42
let test_configuration = mk_configuration toupie quanrante_deux;;
assert (get_jouet test_configuration "LecheCuillere" = Some "toupie");;
assert (get_nb_jouets test_configuration "LecheCuillere" "toupie" = Some 42)
let jouet1 lutin =
match lutin with
| "LecheCuillere" -> Some "toupie"
| "Farceur" -> Some "velo"
| "Malin" -> Some "ballon"
| _ -> None
let jouet2 lutin =
List.assoc_opt lutin
[ ("LecheCuillere", "velo"); ("Farceur", "ballon"); ("Malin", "toupie") ]
let nb_jouets1 lutin _jouet =
List.assoc_opt lutin [ ("LecheCuillere", 1); ("Farceur", 2); ("Malin", 3) ]
let nb_jouets2 _lutin jouet =
List.assoc_opt jouet [ ("velo", 2); ("toupie", 10); ("ballon", 5) ]
let configuration_globale =
List.fold_left
(fun acc (k, v) -> Association.put acc k v)
Association.empty
[
("lundi", mk_configuration toupie quanrante_deux);
("mardi", mk_configuration jouet1 nb_jouets1);
("mercredi", mk_configuration jouet2 nb_jouets1);
("jeudi", mk_configuration jouet1 nb_jouets2);
("vendredi", mk_configuration jouet2 nb_jouets2);
("samedi", mk_configuration jouet1 quanrante_deux);
("dimanche", mk_configuration jouet2 quanrante_deux);
]
let config_samedi =
match Association.get configuration_globale "samedi" with
| Some c -> c
| None -> failwith "pas de configuration pour samedi"
let config_mardi =
match Association.get configuration_globale "mardi" with
| Some c -> c
| None -> failwith "pas de configuration pour mardi"
let lutins = [ "LecheCuillere"; "Farceur"; "Malin" ]
let calcule_jouets_config : configuration -> (string * int) list =
fun cfg ->
let gj = get_jouet cfg and nbj = get_nb_jouets cfg in
let update_jouets jouets lutin =
match gj lutin with
| None -> jouets
| Some jouet -> (
match nbj lutin jouet with
| None -> jouets
| Some nb -> (
match Association.get jouets jouet with
| None -> Association.put jouets jouet nb
| Some nb' -> Association.put jouets jouet (nb + nb')))
in
Association.to_list (List.fold_left update_jouets Association.empty lutins)
;;
assert (
Some 42 = List.assoc_opt "toupie" (calcule_jouets_config config_samedi))
;;
assert (Some 2 = List.assoc_opt "velo" (calcule_jouets_config config_mardi))
end
module LutinsApp = struct
let affiche_jouets : (string * int) list -> string =
fun nb_jouets_du_jour ->
List.fold_left
(fun acc (jouet, nb) ->
if nb = 0 then acc
else
let ligne = jouet ^ ": " ^ string_of_int nb in
if acc = "" then ligne else acc ^ "\n" ^ ligne)
"" nb_jouets_du_jour
end
let usage () = print_endline "\nUsage: ocaml tp7.ml jour"
let run (args : string list) : unit =
match args with
| _pgm :: jour_s :: _ -> (
match Association.get Usine.configuration_globale jour_s with
| Some cfg ->
let quantites = Usine.calcule_jouets_config cfg in
let affichage = LutinsApp.affiche_jouets quantites in
print_endline ("Jouets produits: \n" ^ affichage)
| None -> print_endline (jour_s ^ " n'est pas un jour"))
| _ -> usage ()
let _ = run (Array.to_list Sys.argv)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment