(*** Keep these lines. ***) let qfile = "qqs.ml" ;; let formatter = Format.(make_formatter (fun _ _ _ -> ()) (fun () -> ())) ;; Topdirs.dir_use formatter (if Sys.file_exists qfile then qfile else Sys.getenv "HOME" ^ "/Exam-OCaml/" ^ qfile) ;; (************************************) (***** QUESTION 1 *****) let f1 l = List.filter_map (function Dwarf (n,_) -> Some n | _ -> None) l ;; (* Alternative *) let rec f1 = function | [] -> [] | Dwarf (n,_) :: rest -> n :: f1 rest | _ :: rest -> f1 rest ;; let () = q1 { ff = f1 } ;; (***** QUESTION 2 *****) let f2 l = List.filter_map (function Elf (_,r) -> Some r | _ -> None ) l (* Ou, de manière équivalente *) let rec f2 = function | [] -> [] | Elf (_,r) :: rest -> r :: f2 rest | _ :: rest -> f2 rest ;; let () = q2 { ff = f2 } ;; (***** QUESTION 3 *****) let f3 l = List.fold_left (fun acu -> function Dwarf (_,a) -> min acu a | _ -> acu) max_int l (* Alternative *) let f3 l = let rec loop acu = function | [] -> acu | Dwarf (_, age) :: rest -> loop (min acu age) rest | _ :: rest -> loop acu rest in loop max_int l ;; let () = q3 { ff = f3 } ;; (***** QUESTION 4 *****) let is_elf = function Elf _ -> true | _ -> false let f4 p l = List.exists (fun x -> is_elf x && p x) l ;; (* Alternative *) let rec f4 p = function | [] -> false | Elf _ as elf :: rest -> p elf || f4 p rest | _ :: rest -> f4 p rest ;; let () = q4 { ff = f4 } ;; (***** QUESTION 5 *****) let f5 al = let add_hobbits acu s ln = List.fold_left (fun acu n -> Hobbit(n,s) :: acu) acu ln in List.fold_left (fun acu (s, ln) -> add_hobbits acu s ln) [] al ;; (* Alternative *) let rec f5 = function | [] -> [] | (_, []) :: rest -> f5 rest | (s, n :: ln) :: rest -> Hobbit (n, s) :: (f5 ((s, ln) :: rest)) (* Many alternatives are possible... *) let () = q5 { ff = f5 } ;; ;; (***** QUESTION 6 *****) (* Insert dwarf n with name n into the list. *) let rec insert_dwarf n d acu = function (* The name was not found. Put it in front of the acu list. *) | [] -> (n, [d]) :: acu | (n1, l1) :: rest -> if n1 = n then (* This is the expected slot. Add d here. *) List.rev_append ((n, d :: l1) :: acu) rest else (* Not the right slot. Continue. *) insert_dwarf n d ((n1,l1) :: acu) rest let insert_person asso_list = function | Dwarf (n, _) as d -> insert_dwarf n d [] asso_list | _ -> asso_list let f6 l = List.fold_left insert_person [] l ;; let () = q6 { ff = f6 } ;; (***** QUESTION 7 *****) let get_name = function | Elf (n, _) | Hobbit (n, _) | Dwarf (n, _) -> n (* Explores recursively. The last argument is a room option. * The path is the reversed path to the current room. *) let rec f7_aux n path = function | None -> [] | Some r -> let path = r.tag :: path in if get_name r.guard = n then path (* Bingo *) else let l1 = f7_aux n path r.out1 in if l1 <> [] then l1 (* left branch was successfull *) else f7_aux n path r.out2 (* Try right branch *) let f7 n room = List.rev (f7_aux n [] (Some room)) ;; let () = q7 { ff = f7 } ;;