Problem:
Score : 200 points

Problem Statement

Takahashi is participating in a programming contest called AXC002, and he has just submitted his code to Problem A.

The problem has N test cases.

For each test case i (1\leq i \leq N), you are given a string S_i representing the verdict for that test case. Find the numbers of test cases for which the verdict is AC, WA, TLE, and RE, respectively.

See the Output section for the output format.

Constraints

1 \leq N \leq 10^5

S_i is AC, WA, TLE, or RE.

Input

Input is given from Standard Input in the following format:

N
S_1
\vdots
S_N

Output

Let C_0, C_1, C_2, and C_3 be the numbers of test cases for which the verdict is AC, WA, TLE, and RE, respectively. Print the following:

AC x C_0
WA x C_1
TLE x C_2
RE x C_3

Sample Input 1

6
AC
TLE
AC
AC
WA
TLE

Sample Output 1

AC x 3
WA x 1
TLE x 2
RE x 0

We have 3, 1, 2, and 0 test case(s) for which the verdict is AC, WA, TLE, and RE, respectively.

Sample Input 2

10
AC
AC
AC
AC
AC
AC
AC
AC
AC
AC

Sample Output 2

AC x 10
WA x 0
TLE x 0
RE x 0

Solution in OCaml (4.10.0) (judge verdict: Accepted)

open Batteries
open Printf

let ($) g f x = g (f x)

let swap = Tuple2.swap

let s2i = int_of_string
let i2s = string_of_int
let s2f = float_of_string
let f2s = string_of_float
let c2i = int_of_char
let i2c = char_of_int
let f2i = int_of_float
let i2f = float_of_int 

let c2s = String.of_char
let s2cl = String.to_list
let cl2s = String.of_list

let puts s = print_endline s
let putyn b = puts (if b then "Yes" else "No")
let puti i = puts @@ i2s i

let rep lb bnd ub f = match bnd with
  | `To -> for i = lb to ub do f i done
  | `Til -> for i = lb to (ub - 1) do f i done

let rep2 lb1 bnd1 ub1 () lb2 bnd2 ub2 f = 
  match (bnd1, bnd2) with
  | (`To, `To) -> for i = lb1 to ub1 do for j = lb2 to ub2 do f i j done done
  | (`To, `Til) -> for i = lb1 to ub1 do for j = lb2 to (ub2 - 1) do f i j done done
  | (`Til, `To) -> for i = lb1 to (ub1 - 1) do for j = lb2 to ub2 do f i j done done
  | (`Til, `Til) -> for i = lb1 to (ub1 - 1) do for j = lb2 to (ub2 - 1) do f i j done done

module JunkList = struct
  include List

  let nmem x l = not @@ mem x l

  let len = length
  let size = length
  let nempty l = not @@ is_empty l

  let hdop l = if nempty l then Some (hd l) else None

  (* let taker = drop *)
  let takewh = take_while

  (* let dropr = take *)
  let dropwh = drop_while

  let split_by = span

  let chunk = ntake

  let foldl = fold_left
  let foldli = fold_lefti
  let foldr f z l = fold_right f l z
  let foldri f z l = fold_righti f l z

  let partition_to_map f l =
    foldr (fun x m -> Map.modify_opt (f x) (function
      | None -> Some [x] 
      | Some [] -> Some [x] 
      | Some vl -> Some (x::vl)) m) Map.empty l;;

  let scanl f z ls =
    let rec loop acl acc = function
      | [] -> rev acl
      | h::t ->
        let r = f acc h in
        loop (r::acl) r t
    in loop [] z ls

  let scanr f z ls =
    let rec loop acl acc = function
      | [] -> acl 
      | h::t ->
        let r = f h acc in
        loop (r::acl) r t
    in loop [] z (rev ls)

  (* let scanli = scan_lefti *)
  (* let scanri = scan_righti *)
  
  let flatmap = concat_map

  let zipf = map2
  let zipfi = map2i

end

module L = JunkList

module JunkArray = struct
  include Array 

  let nmem x l = not @@ mem x l

  let len = length
  let size = length
  let is_empty r = len r = 0
  let nempty r = len r > 0

  let take n r = left r n
  let taker n r = right r n

  let takeb x r =
    let l = len r in
    let rec loop i =
      if i >= l then r
      else if r.(i) = x then take i r
      else loop (i + 1)
    in loop 0
     
  (* let takewh = take_while *)

  let drop n r = tail r n
  let dropr n r = take ((len r) - n) r
  (* let dropwh = drop_while *)

  let index_of x r =
    let l = len r in
    let rec loop i =
      if i >= l then None
      else if r.(i) = x then Some i
      else loop (i + 1)
    in loop 0

  (* let split_by = span *)

  (* let chunk = ntake *)

  let foldl = fold_left
  let foldli = fold_lefti
  let foldr f z l = fold_right f l z
  let foldri f z l = fold_righti f l z

  (* let partition_to_map f l = *)
  (*   foldr (fun x m -> Map.modify_opt (f x) (function *)
  (*     | None -> Some [x]  *)
  (*     | Some [] -> Some [x]  *)
  (*     | Some vl -> Some (x::vl)) m) Map.empty l;; *)

  (* let scanl = scan_left *)
  (* let scanli = scan_lefti *)
  (* let scanr = scan_right *)
  (* let scanri = scan_righti *)
  
  let concat2 = append
  
  let flatmap (f : 'a -> 'b array) a =
    map f a |> enum |> L.of_enum |> concat

  let zipf = map2
  (* let zipfi = map2i *)

end

module A = JunkArray

module JunkString = struct
  include String

  let len = length

  let replace_chars = map
  let map = replace

  let maptol f s = L.map f (s2cl s)
  let maptoli f s = L.map f (s2cl s)

  let zipf f a b = L.zipf f (s2cl a) (s2cl b)
  let zipfi f a b = L.zipfi f (s2cl a) (s2cl b)

  let mkstr f sep ls =
    L.foldl (fun acc x -> acc ^ sep ^ (f x)) (f @@ L.hd ls) (List.tl ls)

end

module S = JunkString

let spsp s = S.split_on_char ' ' s


module JunkSortedSet = struct
  include Set

  module Make (Ord : Set.OrderedType) = struct
    include Set.Make(Ord)

    let nmem x st = not @@ mem x st

    let foldl f s z = fold (fun x a -> f a x) z s

    let size = cardinal
  end

  let nmem x st = not @@ mem x st

  let foldl f s z = fold (fun x a -> f a x) z s

  let size = cardinal
end

module Ss = JunkSortedSet

module JunkSortedMap  = struct
  include Map

  module Make (Ord : Map.OrderedType) = struct
    include Map.Make(Ord)

    let nmem x st = not @@ mem x st

    let get = find
    let get_or x d m = find_default d x m

    let size = cardinal
  end

  let nmem x st = not @@ mem x st

  let get = find
  let get_or x d m = find_default d x m

  let size = cardinal
end

module Ms = JunkSortedMap


let set_power ls =
  let rec loop ls pls =
    match ls with
    | [] -> pls
    | hd::tl -> loop tl (L.flatmap (fun p -> [p; hd::p]) pls)
  in loop ls [[]]


exception ArithmeticException of string

module JunkIntArithmetic = struct

  let rec power x e =
    if e = 0 then x
    else 
      let rec loop r x2 e' =
        if e' = 0 then r
        else if e' land 1 = 0 then loop r (x2 * x2) (e' lsr 1)
        else loop (r * x2) (x2 * x2) (e' lsr 1)
      in loop 1 x e

  let rec powers_le_1000 x =
    if x > 32 then [x]
    else
      L.init 9 (fun e -> power x (e + 1))
      |> L.filter (fun y -> y < 1000)

  let primes_le_1000 = [2;3;5;7;11;13;17;19;23;29;31;37;41;
    43;47;53;59;61;67;71;73;79;83;89;97;101;
    103;107;109;113;127;131;137;139;149;151;157;163;167;
    173;179;181;191;193;197;199;211;223;227;229;233;239;
    241;251;257;263;269;271;277;281;283;293;307;311;313;
    317;331;337;347;349;353;359;367;373;379;383;389;397;
    401;409;419;421;431;433;439;443;449;457;461;463;467;
    479;487;491;499;503;509;521;523;541;547;557;563;569;
    571;577;587;593;599;601;607;613;617;619;631;641;643;
    647;653;659;661;673;677;683;691;701;709;719;727;733;
    739;743;751;757;761;769;773;787;797;809;811;821;823;
    827;829;839;853;857;859;863;877;881;883;887;907;911;
    919;929;937;941;947;953;967;971;977;983;991;997]

    let primes_and_powers_le_1000 =
      [2;3;4;5;7;8;9;11;13;16;17;19;23;25;27;29;31;32;37;41;
      43;47;49;53;59;61;64;67;71;73;79;81;83;89;97;
      101;103;107;109;113;121;125;127;128;131;137;139;149;151;
      157;163;167;169;173;179;181;191;193;197;199;211;223;227;
      229;233;239;241;243;251;256;257;263;269;271;277;281;283;
      289;293;307;311;313;317;331;337;343;347;349;353;359;361;
      367;373;379;383;389;397;401;409;419;421;431;433;439;443;
      449;457;461;463;467;479;487;491;499;503;509;512;521;523;
      529;541;547;557;563;569;571;577;587;593;599;601;607;613;
      617;619;625;631;641;643;647;653;659;661;673;677;683;691;
      701;709;719;727;729;733;739;743;751;757;761;769;773;787;
      797;809;811;821;823;827;829;839;841;853;857;859;863;877;
      881;883;887;907;911;919;929;937;941;947;953;961;967;971;
      977;983;991;997]

  let factorize_with ps n =
    let rec loop acc ps e n' =
      if n' <= 1 then ([], n') 
      else
        match ps with
        | [] -> (acc, n')
        | p::t ->
          let r = n' mod p in
          if r = 0 then (
            if n' = p then ((p, e + 1) :: acc, 1)
            else loop acc ps (e + 1) (n' / p)
          ) else
            loop (if e = 0 then acc else (p, e) :: acc) t 0 n'
    in
    let (fs, r) = loop [] ps 0 n in
    (L.rev fs, r)

  let factorize_le_million n =
    factorize_with primes_le_1000 n

  let rec to_bits_le n =
    if n = 0 then []
    else (n mod 2) :: to_bits_le (n lsr 1)

  let rec gcd x y =
    match x mod y with
    | 0 -> y
    | z -> gcd y z

  let ext_euclid a b =
    let rec next (r0, s0, t0) (r1, s1, t1) =
      match r1 with
      | 0 -> (r0, s0, t0)
      | r2 ->
        let q = r0 / r1 in
        next (r1, s1, t1) (r0 - q * r1, s0 - q * s1, t0 - q * t1)
    in
    if a < b then
      let (g, y, x) = next (b, 1, 0) (a, 0, 1) in (g, x, y)
    else
      next (a, 1, 0) (b, 0, 1)

  let modinv x m =
    let (g, y, z) = ext_euclid x m in
    match g with
    | 1 -> y mod m
    | _ -> raise @@ ArithmeticException "Not relatively prime"
      

end

module N = JunkIntArithmetic


let rds () = read_line ()

let rdi () = s2i @@ rds ()

let rdhs () = spsp @@ rds ()
let rdhi () = rdhs () |> L.map s2i

let rdhf () = rdhs () |> L.map s2f

let rdf2 () = match rdhf () with
| a::b::_ -> (a, b)
| _ -> (0., 0.)

let rdf3 () = match rdhf () with
| a::b::c::_ -> (a, b, c)
| _ -> (0., 0., 0.)

let rdf4 () = match rdhf () with
| a::b::c::d::_ -> (a, b, c, d)
| _ -> (0., 0., 0., 0.)

let rds2 () = match rdhs () with
  | a::b::_ -> (a, b)
  | _ -> ("", "")

let rdi2 () = match rdhi () with
  | a::b::_ -> (a, b)
  | _ -> (0, 0)

let rdi3 () = match rdhi () with
| a::b::c::_ -> (a, b, c)
| _ -> (0, 0, 0)

let rdi4 () = match rdhi () with
| a::b::c::d::_ -> (a, b, c, d)
| _ -> (0, 0, 0, 0)

let rdi5 () = match rdhi () with
| a::b::c::d::e::_ -> (a, b, c, d, e)
| _ -> (0, 0, 0, 0, 0)

let rdv n rf =
  let rec loop n =
    if n <= 0 then []
    else (
      let s = rf () in
      s::(loop (n - 1))
    )
  in loop n

let rdvi n = rdv n rdi
let rdvi2 n = rdv n rdi2
let rdvi3 n = rdv n rdi3
let rdvi4 n = rdv n rdi4


let print_list aa = 
  printf "[ "; aa |> L.iter (fun a -> printf "%d " a); puts "]"

let print_array aa = 
  printf "[ "; aa |> A.iter (fun a -> printf "%d " a); puts "]"

let _ =
  let n = rdi () in
  let ss = rdv n rds in
  let res = A.make 4 0 in 

  let inc i = res.(i) <- res.(i) + 1 in

  let rec loop = function
  | [] -> ()
  | "AC"::t -> inc 0; loop t
  | "WA"::t -> inc 1; loop t 
  | "TLE"::t -> inc 2; loop t
  | "RE"::t -> inc 3; loop t
  | _ -> ()
  in

  loop ss;
  printf "AC x %d\nWA x %d\nTLE x %d\nRE x %d\n" res.(0) res.(1) res.(2) res.(3);
  ()