Go: package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

var scanner = bufio.NewScanner(os.Stdin)

func main() {
	for scanner.Scan() {
		var result string
		line := scanner.Text()
		key := make(map[string]string)

		var i int32
		for ; i < 52; i++ {
			makeKey(key, i)
			result = decode(key, line)

			if strings.Contains(result, "the") {
				break
			} else if strings.Contains(result, "this") {
				break
			} else if strings.Contains(result, "that") {
				break
			}
		}

		fmt.Println(result)
	}
}

func makeKey(key map[string]string, shift int32) {
	for i := 'a'; i <= 'z'; i++ {
		cipher := (i + shift)
		if cipher > 'z' {
			cipher = cipher%'z' + 'a' - 1
		} else if cipher < 'a' {
			cipher = cipher + ('z' - 'a') + 1
		}
		key[string(i)] = string(cipher)
	}
}

func decode(key map[string]string, cipher string) string {
	var result string
	for _, v := range cipher {
		if key[string(v)] != "" {
			result += key[string(v)]
		} else {
			result += string(v)
		}
	}
	return result
}

C++: #include <fstream>
#include <iostream>
#include <cmath>
#include <vector>
#include <queue>
#include <utility>
#include <algorithm>
using namespace std;

char shift(char c, int n) {
  if (c >= 'a' && c <= 'z')
    return (c + n <= 'z') ? c + n : 'a' + (c + n - 'z' - 1);
  else
    return c;
}

bool is_abc(char a) {
  return a >= 'a' && a <= 'z';
}

bool exist(string str, string c) {
  int id = str.find(c, 0);
  while (id != string::npos) {
    if (id > 0 && is_abc(str[id-1])) {
      id++;
      id = str.find(c, id);
    } else if (id + c.length() < str.length() && is_abc(str[id + c.length()])) {
      id++;
      id = str.find(c, id);
    } else {
      return true;
    }
  }
  return false;
}

int main() {
  ifstream cin("../test.txt");
  vector<string> _the(26);
  vector<string> _this(26);
  vector<string> _that(26);
  _the[0] = "the";
  _this[0] = "this";
  _that[0] = "that";
  for (int i = 1; i < 26; i++) {
    for (int j = 0; j < 3; j++) {
      _the[i] += shift(_the[0][j], i);
    }
    for (int j = 0; j < 4; j++) {
      _this[i] += shift(_this[0][j], i);
      _that[i] += shift(_that[0][j], i);
    }
  }

  string str, nstr;
  // 復号化
  while (getline(cin, str)) {
    if (str.length() == 0) break;
    nstr = "";
    for (int i = 1; i < 26; i++) {
      if ( exist(str, _the[i]) || exist(str, _this[i]) || exist(str, _that[i])) {
        int len = str.length();
        for (int j = 0; j < len; j++) {
          nstr += shift(str.at(j), 26 - i);
        }
        break;
      }
    }

    cout << nstr << endl;
  }
  // 暗号化
  // while (getline(cin, str)) {
  //   for (int i = 1; i < 26; i++) {
  //     nstr = "";
  //     int len = str.length();
  //     for (int j = 0; j < len; j++) {
  //       nstr += shift(str[j], i);
  //     }
  //     cout << nstr << endl;
  //   }
  // }
}

C++: #include <bits/stdc++.h>

using namespace std;

void f(string &s)
{
    for (char &c : s) {
        if ('a' <= c && c <= 'z') c = (c - 'a' + 25) % 26 + 'a';
    }
}

int main()
{
    string s;

    while (getline(cin, s)) {
        if (s == "") break;
        while (s.find("the") == string::npos || s.find("this") == string::npos || s.find("that") == string::npos) f(s);
        cout << s << endl;
    }
}

C++: #include <iostream>
#include <string>

using namespace std;

int main()
{
  string stro, str;
  while(getline(cin, stro)){
    for(int i = 0; i < 26; i++){
      str = stro;
      for(int j = 0; j < stro.length(); j++){
	if(str[j] != ' ' && str[j] != '.' && str[j] != '\n')
	  if(str[j] + i > 'z')
	    str[j] += i - 26;
	  else
	    str[j] += i;
      }
      unsigned f_the = str.find("the", 0);
      unsigned f_this = str.find("this", 0);
      unsigned f_that = str.find("that", 0);
      if((f_the != string::npos && f_the == 0 && (str[f_the + 3] == ' ' || str[f_the + 3] == '.' || str[f_the + 3] == '\0')) || (f_this != string::npos && f_this == 0 && (str[f_this + 4] == ' ' || str[f_this + 4] == '.' || str[f_this + 4] == '\0')) || (f_that != string::npos && f_that == 0 && (str[f_that + 4] == ' ' || str[f_that + 4] == '.' || str[f_that + 4] == '\0')))
	cout << str << endl;
      else if((f_the != string::npos && (str[f_the - 1] == ' ' || str[f_the - 1] == '.' || str[f_the - 1] == '\n') && (str[f_the + 3] == ' ' || str[f_the + 3] == '.' || str[f_the + 3] == '\0')) || (f_this != string::npos && (str[f_this - 1] == ' ' || str[f_this - 1] == '.' || str[f_this - 1] == '\n') && (str[f_this + 4] == ' ' || str[f_this + 4] == '.' || str[f_this + 4] == '\0')) || (f_that != string::npos && (str[f_that - 1] == ' ' || str[f_that - 1] == '.' || str[f_that - 1] == '\n') && (str[f_that + 4] == ' ' || str[f_that + 4] == '.' || str[f_that + 4] == '\0')))
	cout << str << endl;	 
    }
  }
}

C++: #include <iostream>
using namespace std;
int main(){
    string s;
    int now,last;
    bool found;
    while(getline(cin,s)){
        found=false;
        for(int i=0;i<26;i++){
            for(int j=0;j<s.size();j++)if('a'<=s[j]&&s[j]<='z'){
                s[j]++;
                if(s[j]>'z')s[j]='a';
            }
            last=now=0;
            while(last<s.size()){
                while(now<s.size()&&'a'<=s[now]&&s[now]<='z')now++;
                if(now-last==3){
                    if(s[last]=='t'&&s[last+1]=='h'&&s[last+2]=='e')found=true;
                }
                else if(now-last==4){
                    if(s[last]=='t'&&s[last+1]=='h'){
                        if(s[last+2]=='i'&&s[last+3]=='s')found=true;
                        else if(s[last+2]=='a'&&s[last+3]=='t')found=true;
                    }
                }
                if(found)break;
                now++;
                last=now;
            }
            if(found)break;
        }
        cout<<s<<endl;
    }
}

C++: #include <iostream>
#include <string.h>
#include <string>
#include <stdio.h>
using namespace std;
int main() {
	string w[3]={"the","this","that"},st;
	int wn[3]={3,4,4},k,i,j,s,f;
	while(true) {
    k=0; 
	getline(cin,st);
	while(k<st.size()) {
		for (i=0;i<3;i++) {
			s=0; f=0;
			if (st.size()<k+wn[i]) break;
			for (j=0;j<wn[i]-1;j++) if ((w[i][j]-w[i][j+1])==(st[k+j]-st[k+j+1])) s++;
			if (s==wn[i]-1)  { f=1; i=5;}
		}
		if (f==1) break;
		for (k;st[k]>='a' && st[k]<='z';k++);
		k++;
	}
	if (f==0) cout << st; else {
		for (i=0;i<st.size();i++) 
			if ((st[i]>='a' && st[i]<='z')) cout << (char)(((st[i]-st[k]+'t')-97+26) % 26 + 97) ; 
		    else cout << st[i];
	}
	cout << endl;
	}
	return 0;
	}

C++: #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cassert>
#include<iostream>
#include<sstream>
#include<string>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<utility>
#include<numeric>
#include<algorithm>
#include<bitset>
#include<complex>

using namespace std;

typedef long long Int;
typedef vector<int> vint;
typedef pair<int,int> pint;
#define mp make_pair

template<class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cout << *i << " "; cout << endl; }
template<class T> void chmin(T &t, T f) { if (t > f) t = f; }
template<class T> void chmax(T &t, T f) { if (t < f) t = f; }
int in() { int x; scanf("%d", &x); return x; }

int main() {
	string str;
	for(;getline(cin,str);){
		/*int len=str.size();
		int i,c;
		for(c=1;c<=26;c++){
			for(i=0;i<len;i++){
				if('a'<=str[i]&&str[i]<='z'){
					str[i]++;
					if(str[i]>'z')str[i]='a';
				}
			}
			//cout<<str<<endl;
			if(str.find("the")!=string::npos||str.find("this")!=string::npos||str.find("that")!=string::npos){
				cout<<str<<endl;
				break;
			}
		}*/
	}
	return 0;
}