{ open Lexing open Printf let t = Hashtbl.create 17 let get s = try Hashtbl.find t s with | Not_found -> 0 let incr s = let old = get s in Hashtbl.replace t s (old+1) } rule main = parse | eof {()} | "" {let _ = lire_nom lexbuf in let prenom = lire_prenom lexbuf in incr prenom ; main lexbuf} and lire_nom = parse | [^'(']+ {let lxm = lexeme lexbuf in String.sub lxm 0 (String.length lxm-1)} | "" {failwith "Pas de nom"} and lire_prenom = parse | '(' {vrai_lire_prenom lexbuf} | "" {failwith "Pas de prénom"} and vrai_lire_prenom = parse | [^')']+ ')' {let lxm = lexeme lexbuf in finir_ligne lexbuf ; String.sub lxm 0 (String.length lxm-1)} | "" {failwith "Pas de prénom"} and finir_ligne = parse | [^'\n']* '\n'? {()} { let main chan = main (from_channel chan) ; (* (* Sans trier *) Hashtbl.iter (fun prenom compte -> printf "%s (%d)\n" prenom compte) t *) (* En triant *) let r = ref [] in Hashtbl.iter (fun prenom compte -> r := (prenom, compte) :: !r) t ; let sorted = Sort.list (fun (p1, c1) (p2, c2) -> (c1 >= c2) || (c1 = c2 && p1 <= p2)) !r in List.iter (fun (p, c) -> printf "%s (%d)\n" p c) sorted let _ = main stdin ; exit 0 }