let stream_fold f stream init = let result = ref init in Stream.iter (fun x -> result := f !result x) stream; !result type respondent = { name: string; mutable seq_no: int; score_arr: int array; mutable total_score: int } module StrMap = Map.Make(String) let int_of_qnum str = int_of_char str.[0] - int_of_char 'A' let calc_score n k = 50 * n + (500 * n / (8 + 2 * k)) let read_submit t = Stream.from( fun i -> ( if i < t then let name, qnum = read_line () |> Str.split (Str.regexp_string " ") |> fun lst -> (List.nth lst 0, int_of_qnum (List.nth lst 1)) in Some (name, qnum) else None)) let solve n l_arr sub_st = let qnum_rank_arr = Array.make (Array.length l_arr) 1 in let get_next_seq = (fun () -> let seq_no = ref 0 in fun () -> seq_no := !seq_no + 1; !seq_no) () in let f res_map (name, qnum) = let res_rec = if StrMap.mem name res_map then StrMap.find name res_map else { name = name; seq_no = 0; score_arr = Array.make n 0; total_score = 0 } and rank = qnum_rank_arr.(qnum) and star = l_arr.(qnum) in let score = calc_score star rank in qnum_rank_arr.(qnum) <- rank + 1; res_rec.seq_no <- get_next_seq (); res_rec.score_arr.(qnum) <- score; res_rec.total_score <- res_rec.total_score + score; StrMap.add name res_rec res_map in let ans_lst = StrMap.bindings (stream_fold f sub_st StrMap.empty) |> List.sort (fun (name1, rec1) (name2, rec2) -> compare (-rec1.total_score, rec1.seq_no) (-rec2.total_score, rec2.seq_no)) in List.iteri (fun i (name, record) -> let all_score = Array.fold_left (fun str score -> str ^ " " ^ (string_of_int score)) "" record.score_arr in Printf.printf "%d %s%s %d\n" (i + 1) name all_score record.total_score) ans_lst let () = let n = read_line () |> int_of_string and l_arr = read_line () |> Str.split (Str.regexp_string " ") |> List.map int_of_string |> Array.of_list and t = read_line () |> int_of_string in let sub_st = read_submit t in solve n l_arr sub_st