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
z, inclusive, and is case
insensitive. Input will not contain non-ASCII symbols.
Makefile is provided with a default target to compile your solution and run the tests. At the command line, type:
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
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!
(* 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 ;;
Reducing the problem into independent sub problems and composing their solutions made this easier and clearer.