
public class Crunch {

  public static void main (String[] args) {

    String s = encode ("Oh, frabjuous day.  Calloo!  Callay!", 13);
    System.out.println (s);
    String t = encode (s, -13);
    System.out.println (t);
  }

  // encode: traverses the String and converts the characters
  // one at a time.  Accumulates the result string by appending
  // each character.

  public static String encode (String s, int n) {
    int i = 0;
    String result = "";

    while (i < s.length()) {
      char convertedChar = encodeChar (s.charAt (i), n);
      result += convertedChar;
      i++;
    }
    return result;
  }

  // encodeChar: upper and lower case letters get converted
  // using rotate.  Other characters are left unchanged

  public static char encodeChar (char c, int n) {
    char result = c;
    if (Character.isUpperCase (c)) {      
      result = rotate (c, n, 'A', 'Z');
    } else if (Character.isLowerCase (c)) {
      result = rotate (c, n, 'a', 'z');
    }
    return result;
  }

  // rotate: this method has been generalized to deal with both
  // upper and lower case letters, depending on the values
  // of low and high

  public static char rotate (char c, int n, char low, char high) {
    int result = c + n;
    if (result > high) result -= (high - low + 1);
    else if (result < low) result += (high - low + 1);
    return (char)result;
  }
}



