Hi, I'm Ataias Reis

Programmer, made in Brazil, Alma mater University of Brasilia

Compare Triplets in OCaml

Hi there! It has been a while since I played with OCaml, so I am solving a simple problem from HackerRank. The problem says the following “Alice and Bob each created one problem for HackerRank. A reviewer rates the two challenges, awarding points on a scale from 1 to 100 for three categories: problem clarity, originality, and difficulty”.

For each category, we must check who had a greater score and give a point to that person for each category. This way, the maximum grade is 3 and the minimum is 0. An example input/output is:

# input
5 6 7
3 6 10
# output
1 1 # the score for Alice, then for Bob

The end result is the code below.

open Core.Std
type rating = {
    x1 : int;
    x2 : int;
    x3 : int;
  }

let get_line () =
  In_channel.input_line In_channel.stdin

(* When parsing with String.split,
  some elements may be empty,
  so we remove them *)
let remove_empty l =
  let not_empty x = x <> "" in
  List.filter ~f:not_empty l

(* Magic happens, returns list of numbers*)
let parse line =
  let l = String.split line ~on:' ' in
  let number_str = remove_empty l in
  List.map number_str ~f:Int.of_string

let to_record list =
  match list with
  | x1::x2::x3::[] -> {x1; x2; x3}
  (* Not having the 3 numbers is an error*)
  | _ -> assert false;;

let read_triplet () =
  match get_line () with
    | None -> [0;0;0]
    | Some x -> parse x

let a = to_record (read_triplet ())
let b = to_record (read_triplet ())

let grade x y =
  let f a b = if a > b then 1 else 0 in
  (f x.x1 y.x1) +
    (f x.x2 y.x2) +
    (f x.x3 y.x3)

let grade_a = grade a b
let grade_b = grade b a
let () = printf "%d %d" grade_a grade_b

My comments: this was kind of hard. Why? It has been almost three years since I coded in OCaml and the concepts are not fresh on my mind of how I coded at the time. For instance, initially I was pattern matching on two elements of a list using a recursive function instead of the three elements, without a recursive function. This was cumbersome and I think it is much better in the final version, matching with 3 elements and raising an error. One thing that caused me problems was trying to use variables with first letters capitalized, as this is reserved for modules.

Note: later I discovered there is a function called read_int in OCaml. This could have made my life simpler, I think.

Thanks for reading!

Tags
comments powered by Disqus