#load "str.cma";;

(*
 * The function isPalindrome checks if a given character string is a palindrome,
 * i.e. it is identical whether being read from left to right or from right to
 * left. Note that this function removes punctuation and word dividers before
 * checking the given character string.
 *)
let isPalindrome raw =
    (*
     * Check if the left and right character of the string are the same. An
     * empty string and a string with length 1 is by definition a palindrome.
     * Check uses a character string `s' and its length `l' to recursively
     * determine if `s' is a palindrome.
     *)
    let rec check s l =
        l < 2 || (s.[0] == s.[l-1] && (check (String.sub s 1 (l-2)) (l-2)))
    in
    (* Remove punctuation / word dividers -> only alphanumeric chars remain. *)
    let filter = Str.regexp "[^a-zA-Z0-9]+" in
    let filtered = String.lowercase (Str.global_replace filter "" raw) in
        (check filtered (String.length filtered))
;;

let test_isPalindrome str =
    Printf.printf "isPalindrome(\"%s\") -> %b\n" str (isPalindrome str)
;;

test_isPalindrome "";;
test_isPalindrome "a";;
test_isPalindrome "baas saab";;
test_isPalindrome "never odd or even";;
test_isPalindrome "Was it a rat i saw?";;

test_isPalindrome "expected failure!";;
