my-solutions/codewars/ocaml/rank-up/statistics-for-an-athletic-association/main.ml

41 lines
1.5 KiB
OCaml
Raw Permalink Normal View History

2024-02-20 22:19:58 +05:00
let to_seconds (s : string) : int =
let raw_digits = String.split_on_char '|' s in
let digits = List.map (fun x -> (int_of_string x)) raw_digits in
List.fold_left (fun acc i -> (acc * 60 + i)) 0 digits;;
let seconds_to_time (total_sec : int) : string =
let hours = total_sec / 3600 in
let minutes = (total_sec - hours * 3600) / 60 in
Printf.sprintf "%02d|%02d|%02d" hours minutes (total_sec - hours * 3600 - minutes * 60);;
let range (l : int list) : int =
let min = List.fold_left Int.min Int.max_int l in
let max = List.fold_left Int.max 0 l in
max - min;;
let avg (l : int list) : float =
let sum = List.fold_left Int.add 0 l in
(float_of_int sum) /. (float_of_int (List.length l));;
let median (l : int list) : float =
let sorted = List.sort compare l in
let len = List.length l in
match len mod 2 with
| 0 -> float_of_int ((List.nth sorted (len / 2 - 1)) + (List.nth sorted (len / 2))) /. 2.0
| 1 -> float_of_int (List.nth sorted (len / 2))
| x -> 0.0;;
let stat (s : string) : string =
match s with
| "" -> ""
| s -> (
let raw_results = List.map String.trim (String.split_on_char ',' s) in
let res_in_seconds = List.map to_seconds raw_results in
let range_str = seconds_to_time (range res_in_seconds) in
let avg_str = seconds_to_time (int_of_float (avg res_in_seconds)) in
let median_str = seconds_to_time (int_of_float (median res_in_seconds)) in
Printf.sprintf "Range: %s Average: %s Median: %s" range_str avg_str median_str
);;