public class TestPalindrome{
  /** return true iff candidate is a palindrome.
   */
  public static boolean isPalindrome(String candidate){
    if (candidate == null) { return false; } // not even a string

    boolean palindromeSoFar = true; // until proven otherwise

    // Compare pairwise until the middle
    for (int i=0;  (i<candidate.length()/2  && palindromeSoFar) ; i++){
      if (candidate.charAt(i) !=
	  candidate.charAt((candidate.length() - 1) - i) ){
	palindromeSoFar = false;	
      }
    }
    return palindromeSoFar;
  }

  /** return true iff candidate is a palindrome once it
   *  has been converted to lower case and had non-numeric
   * characters removed.
   */
  public static boolean isLoosePalindrome(String candidate){
    if (candidate == null) { return false; } // not a string

    // alpha-only, all lower case version of candidate
    String prunedCandidate = "";
    candidate = candidate.toLowerCase(); // convert parameter

    for (int i=0; i<candidate.length(); i++){
      if (Character.isLetter(candidate.charAt(i))){
	prunedCandidate += candidate.charAt(i);
      }
    }
    return isPalindrome(prunedCandidate);
  }

  /** return true iff candidate is a strict palindrome */
  private static void testPalindrome(String candidate){
    if (candidate != null){
      System.out.println( "\""+candidate+"\"" + " is a palindrome: " +
			  isPalindrome(candidate) );
    }else{
      System.out.println( candidate + " is a palindrome: " +
			 isPalindrome(candidate) );
    }
  }

  /** return true iff candidate is a loose palindrome */
  private static void testLoosePalindrome(String candidate){
    if (candidate != null){
      System.out.println( "\""+candidate+"\"" + " is a loose palindrome: " +
			  isLoosePalindrome(candidate) );
    }else{
      System.out.println(candidate + " is a loose palindrome: " +
			 isLoosePalindrome(candidate));
    }
  }

  /** test some candidates to see whether they are palindromes */
  public static void main(String[] args){
    testPalindrome(""); //empty string is a palindrome
    testPalindrome("X"); // single character is a palindrome
    testPalindrome("abcdefghijklmnopq"); // long, non-palindrome
    testPalindrome("az"); // short non-palindrome
    testPalindrome("zz"); // short palindrome
    testPalindrome("ankleTelkna"); // longer odd-length palindrome
    testPalindrome("anlkeTwoble"); // longer odd-length non-palindrome
    testPalindrome("FasttsaF"); // longer even-length palindrome
    testPalindrome(null); // non-string non-palindrome
    testPalindrome("a2B7B2a"); // alphanumeric palindrome
    testPalindrome("&3*73*&"); // alpha-numeric-symbols non-palindrome
    testLoosePalindrome("A man, a plan, a canal --- Panama!");
    testLoosePalindrome("Coming and going!");
  }
}
      

