Avatar of barisere

barisere's solution

to Pangram in the OCaml Track

Published at Sep 20 2019 · 0 comments
Instructions
Test suite
Solution

Determine if a sentence is a pangram. A pangram (Greek: παν γράμμα, pan gramma, "every letter") is a sentence using every letter of the alphabet at least once. The best known English pangram is:

The quick brown fox jumps over the lazy dog.

The alphabet used consists of ASCII letters a to z, inclusive, and is case insensitive. Input will not contain non-ASCII symbols.

Getting Started

  1. Install the Exercism CLI.

  2. Install OCaml.

  3. For library documentation, follow Useful OCaml resources.

Running Tests

A Makefile is provided with a default target to compile your solution and run the tests. At the command line, type:

make

Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

Feedback, Issues, Pull Requests

The exercism/ocaml repository on GitHub is the home for all of the Ocaml exercises.

If you have feedback about an exercise, or want to help implementing a new one, head over there and create an issue or submit a PR. We welcome new contributors!

Source

Wikipedia https://en.wikipedia.org/wiki/Pangram

test.ml

(* pangram - 1.4.1 *)
open OUnit2
open Pangram

let ae exp got _test_ctxt = assert_equal ~printer:string_of_bool exp got

let tests = [
  "sentence empty" >::
  ae false (is_pangram "");
  "recognizes a perfect lower case pangram" >::
  ae true (is_pangram "abcdefghijklmnopqrstuvwxyz");
  "pangram with only lower case" >::
  ae true (is_pangram "the quick brown fox jumps over the lazy dog");
  "missing character 'x'" >::
  ae false (is_pangram "a quick movement of the enemy will jeopardize five gunboats");
  "another missing character, e.g. 'h'" >::
  ae false (is_pangram "five boxing wizards jump quickly at it");
  "pangram with underscores" >::
  ae true (is_pangram "the_quick_brown_fox_jumps_over_the_lazy_dog");
  "pangram with numbers" >::
  ae true (is_pangram "the 1 quick brown fox jumps over the 2 lazy dogs");
  "missing letters replaced by numbers" >::
  ae false (is_pangram "7h3 qu1ck brown fox jumps ov3r 7h3 lazy dog");
  "pangram with mixed case and punctuation" >::
  ae true (is_pangram "\"Five quacking Zephyrs jolt my wax bed.\"");
  "upper and lower case versions of the same character should not be counted separately" >::
  ae false (is_pangram "the quick brown fox jumps over with lazy FX");
]

let () =
  run_test_tt_main ("pangram tests" >::: tests)
open Base;;

(** Make a Set containing the characters in s that pass the predicate f *)
let set_of_chars ~f s =
  String.fold ~init:(Set.empty (module Char))
    ~f:(fun acc c -> if f c then Set.add acc c else acc)
    s
;;

(** Concat all characters in set into a string *)
let char_set_to_string set =
  Set.fold ~init:"" ~f:(fun acc e -> acc ^ Char.to_string e) set
;;

(** Extract a string that contains only alphabetic characters *)
let extract_unique_chars s = s |> set_of_chars ~f:Char.is_alpha |> char_set_to_string
;;

(** Compute the sum of the ASCII codes of the characters in a string *)
let sum_chars = String.sum (module Int) ~f:Char.to_int;;

(** Compute the sum of the first n natural numbers *)
let sum_of_first_n n = (n * n + n) / 2;;

(** The sum of the lowercase ASCII character codes *)
let sum_lowercase_alpha =
  sum_of_first_n (Char.to_int 'z') - sum_of_first_n (Char.to_int 'a' - 1);;

let is_pangram s =
  String.lowercase s
  |> extract_unique_chars
  |> sum_chars
  |> (=) sum_lowercase_alpha
;;

Community comments

Find this solution interesting? Ask the author a question to learn more.

barisere's Reflection

Reducing the problem into independent sub problems and composing their solutions made this easier and clearer.