1
\$\begingroup\$

the code implements this code kata: https://codingdojo.org/kata/Diamond/ This is my very first ocaml program, looking for any kind of feedback, as I'm a total ocaml noob.

It uses JaneStreet's Base and Stdio as well as cmdliner.

open Base
open Printf
open Stdio
open Cmdliner

exception DiamondError of string

let ascii_a = Char.to_int 'A'

let const_init_list n elem = 
  List.init n ~f: (fun _ -> elem)

let make_line depth i = if depth = 1 then
  ['A']
else 
  let line_width = 2 * depth - 1 in
  if i = 0 then 
    let dots = const_init_list ((line_width - 1) / 2) ' ' in
    dots @ ['A'] @ dots
  else
    let n_inner_dots = (i - 1) * 2 + 1 in
    let n_outer_dots = (line_width - n_inner_dots - 2) / 2 in
    let outer_dots = const_init_list n_outer_dots ' ' in
    let inner_dots = const_init_list n_inner_dots ' ' in
    let char_list = [Char.of_int_exn (ascii_a + i)] in
    outer_dots @ char_list @ inner_dots @ char_list @ outer_dots

let get_upper_triangle d = 
  List.init d ~f: (fun i -> make_line d i |> String.of_char_list) 

let render_diamond letter = 
  let triangle_depth = Char.to_int letter - ascii_a + 1 in
  if triangle_depth < 0 || triangle_depth > 26 then
    raise @@ DiamondError (sprintf "%c is invalid" letter)
  else 
    let upper_triangle = get_upper_triangle triangle_depth in
    if triangle_depth > 1 then 
      upper_triangle @ (List.tl_exn @@ List.rev upper_triangle)
    else
      upper_triangle
  
let main letter = 
  let diamond = try render_diamond letter  with 
    DiamondError s -> print_endline(s); Stdlib.exit 1 
  in 
  List.iter ~f: print_endline diamond

let letter  = 
  let doc = "The letter that determines which diamond is printed" in
  Arg.(required & pos 0 (some char) None & info [] ~doc ~docv:"LETTER")

let render_diamond_t = Term.(const main $ letter)
let cmd = Cmd.v (Cmd.info "diamond") render_diamond_t
let () = Stdlib.exit @@ Cmd.eval cmd
\$\endgroup\$
2
  • \$\begingroup\$ Minor note: in const_init_list you can replace (fun _ -> elem) with (Fn.const elem) from Base or (Fun.const elem) from Stdlib. \$\endgroup\$
    – Chris
    Apr 4 at 19:53
  • \$\begingroup\$ I had a feeling this function must exist, but didn't find it. Thanks :) \$\endgroup\$
    – FelixGK
    Apr 6 at 6:43

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.