Go: package main

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

var scanner = bufio.NewScanner(os.Stdin)

func nextString() string {
	scanner.Scan()
	return scanner.Text()
}

func cipher(text string, direction int, int_shift int) string {
	shift, offset := rune(int_shift), rune(26)
	runes := []rune(text)
	for index, char := range runes {
		switch direction {
		case 1:
			if char >= 'a' && char <= 'z'-shift || char >= 'A' && char <= 'Z'-shift {
				char = char + shift
			} else if char > 'z'-shift && char <= 'z' || char > 'Z'-shift && char <= 'Z' {
				char = char + shift - offset
			}
		case -1:
			if char >= 'a'+shift && char <= 'z' || char >= 'A'+shift && char <= 'Z' {
				char = char - shift
			} else if char >= 'a' && char < 'a'+shift || char >= 'A' && char < 'A'+shift {
				char = char - shift + offset
			}
		}
		runes[index] = char
	}
	return string(runes)
}

func main() {
	for {
		infos := strings.Split(nextString(), " ")
		plain := make([]string, len(infos))
		if len(infos) == 0 {
			break
		}
		// println(infos)
		Decryption:
			for i := 0; i < 26; i++ {
				for j := range infos {
					plain[j] = cipher(infos[j], 1, i)
				}
				for j := range plain {
					if plain[j] == "this" || plain[j] == "that" || plain[j] == "the" {
						break Decryption
					}
				}
			}
			fmt.Println(strings.Join(plain, " "))
	}
}

C++: #include<cstdio>
#include<cctype>
#include<cstring>
using namespace std;
int main(){
    int f = 0;
    char str[100] = {0};
    while(scanf("%[^\n]",str) != EOF){
        fflush(stdin);
        for(int i = 0;i <= 25; i++){
            for(int j = 0;j < strlen(str); j++){
                if(str[j] == '\n' || str[j] == '.')continue;
                str[j] += 1;
            }
            for(int k = 0;k < strlen(str); k++){
                if(str[k] == 't' &&  str[k+1] == 'h' && str[k+2] == 'e')goto hoge;
                if(str[k] == 't' &&  str[k+1] == 'h' && str[k+2] == 'i' && str[k+3] == 's')goto hoge;
                if(str[k] == 't' &&  str[k+1] == 'h' && str[k+2] == 'a' && str[k+3] == 't')goto hoge;
            }
        }
        for(int i = 0;i < strlen(str); i++){
            if(str[i] == '\n' || str[i] == '.')continue;
            str[i] -= 25;
        }

        for(int i = 0;i <= 25; i++){
            for(int j = 0; j< strlen(str); j++){
                if(str[j] == '\n' || str[j] == '.')continue;
                str[j] -= 1;
            }
            for(int k = 0;k < strlen(str); k++){
                    if(str[k] == 't' &&  str[k+1] == 'h' && str[k+2] == 'e')goto hoge;
                    if(str[k] == 't' &&  str[k+1] == 'h' && str[k+2] == 'i' && str[k+3] == 's')goto hoge;
                    if(str[k] == 't' &&  str[k+1] == 'h' && str[k+2] == 'a' && str[k+3] == 't')goto hoge;
            }
        }

        hoge:

        for(int i = 0;i < strlen(str)-1; i++)if(str[i] == 46)str[i] = ' ';
        printf("%s\n",str);
        //for(int i = 0;i < strlen(str); i++)str[i] = 0;
        //getchar();
    }
    return 0;
}

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;
    }
}