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) ;;
let f1 l = List.filter_map (function Dwarf (n,_) -> Some n | _ -> None) l
;;
let rec f1 = function
| [] -> []
| Dwarf (n,_) :: rest -> n :: f1 rest
| _ :: rest -> f1 rest
;;
let () = q1 { ff = f1 } ;;
let f2 l = List.filter_map (function Elf (_,r) -> Some r | _ -> None ) l
let rec f2 = function
| [] -> []
| Elf (_,r) :: rest -> r :: f2 rest
| _ :: rest -> f2 rest
;;
let () = q2 { ff = f2 } ;;
let f3 l = List.fold_left (fun acu -> function Dwarf (_,a) -> min acu a | _ -> acu) max_int l
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 } ;;
let is_elf = function Elf _ -> true | _ -> false
let f4 p l = List.exists (fun x -> is_elf x && p x) l
;;
let rec f4 p = function
| [] -> false
| Elf _ as elf :: rest -> p elf || f4 p rest
| _ :: rest -> f4 p rest
;;
let () = q4 { ff = f4 } ;;
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
;;
let rec f5 = function
| [] -> []
| (_, []) :: rest -> f5 rest
| (s, n :: ln) :: rest -> Hobbit (n, s) :: (f5 ((s, ln) :: rest))
let () = q5 { ff = f5 } ;;
;;
let rec insert_dwarf n d acu = function
| [] -> (n, [d]) :: acu
| (n1, l1) :: rest ->
if n1 = n then
List.rev_append ((n, d :: l1) :: acu) rest
else
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 } ;;
let get_name = function
| Elf (n, _) | Hobbit (n, _) | Dwarf (n, _) -> n
let rec f7_aux n path = function
| None -> []
| Some r ->
let path = r.tag :: path in
if get_name r.guard = n then path
else
let l1 = f7_aux n path r.out1 in
if l1 <> [] then l1
else f7_aux n path r.out2
let f7 n room = List.rev (f7_aux n [] (Some room))
;;
let () = q7 { ff = f7 } ;;