Problem:
Caesar Cipher

In cryptography, Caesar cipher is one of the simplest and most widely known encryption method. Caesar cipher is a type of substitution cipher in which each letter in the text is replaced by a letter some fixed number of positions down the alphabet. For example, with a shift of 1, 'a' would be replaced by 'b', 'b' would become 'c', 'y' would become 'z', 'z' would become 'a', and so on. In that case, a text:

this is a pen

is would become:

uijt jt b qfo

Write a program which reads a text encrypted by Caesar Chipher and prints the corresponding decoded text. The number of shift is secret and it depends on datasets, but you can assume that the decoded text includes any of the following words: "the", "this", or "that".

Input

Input consists of several datasets. Each dataset consists of texts in a line. Input ends with EOF. The text consists of lower-case letters, periods, space, and end-of-lines. Only the letters have been encrypted. A line consists of at most 80 characters.

You may assume that you can create one decoded text which includes any of "the", "this", or "that" from the given input text.

The number of datasets is less than or equal to 20.

Output

Print decoded texts in a line.

Sample Input

xlmw mw xli tmgxyvi xlex m xsso mr xli xvmt.

Output for the Sample Input

this is the picture that i took in the trip.

Solution in JAVA (judge verdict: Wrong Answer)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

class Main{
	
	public static Integer encryptStep = null;
	public static String encryptedMessage = "";
	public static String decryptedMessage = "";
	
	public static void main(String args[]) throws IOException{
		BufferedReader inMsg = new BufferedReader(new InputStreamReader(System.in));
		
			while ((encryptedMessage = inMsg.readLine()) != null) {
				decryptedMessage = "";
				
				findEncryptStep(encryptedMessage);
				
				if(encryptStep != null){
					convertMsg();
					System.out.println(decryptedMessage);
					break;
				} 
//				else {
//					// ????????????????????´????????????????????????
//					System.out.println(encryptedMessage);
//					break;
//				}
			}

	}
	
	/**
	 * ?????????????????¨??????????????????????????¢??????
	 * @param msg
	 */
	public static void findEncryptStep(String msg){
		// Scanner encryptedMsg;
		String[] words;
		
		if(msg.contains(".")){
			msg = msg.replace(".", "");
		}
		// encryptedMsg = new Scanner(encMsg);
		
		words = msg.split(" ");
		
        for (String word : words) {
        	checkWords(word);
        	if(encryptStep!=null){
	    		break;
	    	}
        }
        
	    //while (encryptedMsg.hasNext()) {
//	    	
//	    	words = encryptedMsg.next();
//	    	checkWords(words);
//	    	if(encryptStep!=null){
//	    		break;
//	    	}
//	    	
//	    }
		
	}
	
	/**
	 *  ???????????????????????????
	 */
	public static void convertMsg(){
		
		int len = encryptedMessage.length();
		
		for(int i = 0; i<len ; i++){
			decryptedMessage = decryptedMessage + shiftChars(encryptedMessage.charAt(i));
		}
	}
	
	/**
	 * ???????????????????????§??????????????????
	 * @param chr
	 * @return
	 */
	public static char shiftChars(char chr){
		
		int shifted = 0;
		
		if(chr == ' ' || chr == '.'){
			return chr;
		}

		if(chr >= 'a' && chr <= 'z'){
			shifted = chr - encryptStep;
			
			if(shifted > 'z'){
				shifted = ('a' - 1)  + (shifted - 'z');
			} else if(shifted < 'a'){
				shifted  = ('z' + 1) - ('a' - shifted);
			}
		}
		
		return (char)shifted;
	}
	
	/**
	 * ?????????THE???THIS???THAT?????????????????§???????????¨????¢??????????
	 * ?????????????????¨???????????????????????????????????????
	 * @param words
	 */
	public static void checkWords(String words){
		final int DIFF_T_AND_H = 12;
		final int DIFF_H_AND_E = 3;
		final int DIFF_H_AND_I = -1;
		final int DIFF_I_AND_S = -10;
		final int DIFF_H_AND_A = -7;
		final int DIFF_A_AND_T = -9;
		
		int wordLen = words.length();
		int firstChar = 0;
		int secChar = 0;
		int thirdChar = 0;
		
    	if(3 < wordLen){
    		
    		firstChar = countAsciiStep(words.charAt(0), words.charAt(1));
    		secChar = countAsciiStep(words.charAt(1), words.charAt(2));
    		
    		//???????????\??????????????????TH??§?§??????£????????????????¢????
    		if(firstChar == DIFF_T_AND_H){
    			// ?????????????????????THE??§???????????¨????¢????
    			if(wordLen == 3 && secChar == DIFF_H_AND_E){
    				encryptStep = countAsciiStep(words.charAt(0),'t');
    			} else if(wordLen == 4){
    	    		thirdChar = countAsciiStep(words.charAt(2),words.charAt(3));
    	   			// 4??????????????????THIS?????????THAT??§???????????¨????¢????
    	    		if((secChar == DIFF_H_AND_I && thirdChar == DIFF_I_AND_S) 
    	    				|| (secChar == DIFF_H_AND_A && thirdChar == DIFF_A_AND_T)){
    	    			encryptStep = countAsciiStep(words.charAt(0),'t');
    	    		}
    	    	}
    		}
    	}
    	
	}
	
	/**
	 * 2?????????????????????????????????????????????
	 * @param a
	 * @param b
	 * @return
	 */
	public static int countAsciiStep(char a, char b){
		int firstLetter = a;
		int secondLetter = b;
		int stepCounter = 0;
		boolean minus = false;
		
		if(a < b){
			firstLetter = b;
			secondLetter = a;
			minus = true;
		}
		
		while(secondLetter < firstLetter){
			
			firstLetter --;
			
			stepCounter ++;
			
			// a???????°??????????????????????????????§???????????????????£???£??????
			if(firstLetter < 'a'){
				firstLetter = 'z';
			} else if(firstLetter > 'z'){
				firstLetter = 'a';
			}
		}
		
		if(minus){
			stepCounter = -1 * stepCounter;
		}
		
		return stepCounter;
	}
}