//ヘッダファイルのインクルード
#include<stdio.h>

//マクロ定義
#define TRUE 1
#define FALSE 0
#define MAX 81 //入力の最大文字数は80,それに\0を追加して81
#define ALPHABET 26 //非減算数に+して使う

#define compile 0 //デバッグ用
/*
0:実装 1:mainのデバッグ 2:cal_diffのデバッグ 3:get_key3のデバッグ
4:get_key4のデバッグ 5:decordのデバッグ
*/

//関数のプロトタイプ宣言
void func_init(char array[]); //char型配列の初期化を行う関数
int func_cal_diff(char array[]); //復号用の鍵を取得する関数
int func_get_key3(char input[], char key_c[], int key_n[]); //文字列を判別して鍵の値を渡す関数
int func_get_key4(char input[], char key_c[], int key_n[]); //文字列を判別して鍵の値を渡す関数
void func_decord(char array[], char result[], int key); //与えられた暗号文を復号する関数
void func_output(char array[]); //出力を行う関数

main()
{
	char input_str[MAX]; //入力用の配列,最大要素数は81
	char result_str[MAX]; //出力用の配列,最大要素数は81
	func_init(input_str); //input_strの初期化
	func_init(result_str); //result_strの初期化
	
	int diff = 0; //何文字分後ろにずらすかを決める変数
	
	while(gets(input_str) != NULL) //無限ループ(ループを抜ける条件はループ内にある)
	{
#if compile == 1
		printf("input_str = %s\n", input_str);
#endif
		diff = func_cal_diff(input_str); //何文字分ずらすかを計算する
#if compile == 1
		printf("diff = %d\n", diff);
#endif
		func_decord(input_str, result_str, diff); //復号
		func_output(result_str); //出力
		func_init(input_str); //input_strの初期化
		func_init(result_str); //result_strの初期化
	}
	return 0;
}
//------------------------------------------------------------------------------------------------------------------------
void func_init(char array[]) //char型配列の初期化を行う関数
{
	int i = 0;
	for(i = 0; i < MAX; i++) //iの増加量は1,iがMAX-1になるまでループを繰り返す
	{
		array[i] = 0x00; //arrayのi番目の要素ににヌル文字を代入
	}
}
//------------------------------------------------------------------------------------------------------------------------
int func_cal_diff(char array[]) //復号用の鍵を返却値とする関数
{
	int i = 0, j = 0, n_the = 0, n_that = 0, n_this = 0; //i,jは制御変数,nは復号時に使用する鍵
	char key_the[] = {'t', 'h', 'e'}; //鍵取得用の配列theを宣言
	char key_that[] = {'t', 'h', 'a', 't'}; //鍵取得用の配列thatを宣言
	char key_this[] = {'t', 'h', 'i', 's'}; //鍵取得用の配列thisを宣言
	int key_theN[3] = {0, 0, 0}; //key_theとセットで使う
	int key_thatN[4] = {0, 0, 0, 0}; //key_thatとセットで使う
	int key_thisN[4] = {0, 0, 0, 0}; //key_thisとセットで使う
	
#if compile == 2
	printf("array = %s @ func_cal_diff\n", array);
#endif
	n_the = func_get_key3(array, key_the, key_theN); //nにはTRUEorFALSEが返ってくる
	
	if(TRUE == n_the) //n_theが鍵の取得に成功していたら
	{
		n_the = key_theN[0]; //鍵は配列内のどの要素でもいい
		
#if compile == 2 //デバッグ用
		printf("n_the = %d\n", n_the);
#endif
		
		return n_the; //鍵の値を返却値とする
	}
	
	if(TRUE != n_the) //n_theが鍵の取得に失敗していたら
	{
		
#if compile == 2
		printf("n_that = func_get_key4(array, key_that, key_thatN);でのコール\n");
#endif
		
		n_that = func_get_key4(array, key_that, key_thatN); //n_thatにはTRUEorFALSEが返ってくる
		if(TRUE == n_that)
		{
			n_that = key_thatN[0]; //鍵は配列内のどの要素でもいい
#if compile == 2
			printf("n_that = %d\n", n_that);
#endif
			return n_that; //鍵の値を返却値とする
		}
	}
	
	if((TRUE != n_that) && (TRUE != n_the)) //n_thatが鍵の取得に失敗していたら
	{
		
#if compile == 2
		printf("n_this = func_get_key4(array, key_this, key_thisN);でのコール\n");
#endif
		
		n_this = func_get_key4(array, key_this, key_thisN); //nにはTRUEorFALSEが返ってくる
		if(TRUE == n_this)
		{
#if compile == 2
			printf("n_this = %d\n", n_this);
#endif
			n_this = key_thisN[0]; //鍵は配列内のどの要素でもいい
			return n_this; //鍵の値を返却値とする
		}
	}
}
//------------------------------------------------------------------------------------------------------------------------
int func_get_key3(char input[], char key_c[], int key_n[]) //文字列を判別して鍵の値を渡す関数
{
	int i = 0; //iは制御変数
	for(i = 0; input[i] != 0; i++) //input[i]の中身がヌル文字になるまでループ
	{
		if(input[i] < key_c[0]) //
		{
			key_n[0] = (input[i] + ALPHABET) - key_c[0];
		}
		else
		{
			key_n[0] = input[i] - key_c[0];
		}
		if(input[i + 1] < key_c[1])
		{
			key_n[1] = (input[i + 1] + ALPHABET) - key_c[1];
		}
		else
		{
			key_n[1] = input[i + 1] - key_c[1];
		}
		if(input[i + 2] < key_c[2])
		{
			key_n[2] = (input[i + 2] + ALPHABET) - key_c[2];
		}
		else
		{
			key_n[2] = input[i + 2] - key_c[2];
		}
		
#if compile == 3
		printf("func_get_key3 %d回目のループ key[0] = %d key[1] = %d key[2] = %d\n", i, key_n[0], key_n[1], key_n[2]);
#endif
		
		if((key_n[0] == key_n[1]) && (key_n[0] == key_n[2]))
		/*
		key_n[0],key_n[1],key_n[2]の3つが全て同値である場合{}内の処理を行う
		*/
		{
			if((i == 0) && ((97 >= input[i + 3]) || (122 <= input[i + 3])))
			/*
			iの値が0の場合は前の要素を参照できないのでここで処理を分岐
			要素番号i+3の要素が文字以外である場合
			*/
			{
				
#if compile == 3 //デバッグ用,if((i == 0) && ((97 >= input[i + 3]) || (122 <= input[i + 3])))が真である場合に動作
				printf("return TRUE\n");
#endif
				
				return TRUE; //鍵取得成功
			}
			else if(((97 >= input[i - 1]) || (122 <= input[i - 1])) && ((97 >= input[i + 3]) || (122 <= input[i + 3])))
			/*
			iの値が0以外の場合ではi-1の要素とi+3の要素を参照する必要がある
			2つの要素がアルファベットでない場合はTRUEを返す
			*/
			{
				
#if compile == 3 
				/*
				デバッグ用,else if(((97 >= input[i - 1]) && (122 <= input[i - 1])) && ((97 >= input[i + 3]) && (122 <= input[i + 3])))
				が真である場合に動作
				*/
				printf("return TRUE\n");
#endif
				
				return TRUE; //鍵取得成功
			}
		}
	}
	
#if compile == 3
	printf("return FALSE\n");
#endif
	
	return FALSE; //鍵取得失敗
}
//------------------------------------------------------------------------------------------------------------------------
int func_get_key4(char input[], char key_c[], int key_n[]) //文字列を判別して鍵の値を渡す関数
{
	int i = 0; //iは制御変数
	for(i = 0; input[i] != 0; i++)
	{
		if(input[i] < key_c[0])
		{
			key_n[0] = (input[i] + ALPHABET) - key_c[0];
		}
		else
		{
			key_n[0] = input[i] - key_c[0];
		}
		
		if(input[i + 1] < key_c[1])
		{
			key_n[1] = (input[i + 1] + ALPHABET) - key_c[1];
		}
		else
		{
			key_n[1] = input[i + 1] - key_c[1];
		}
		
		if(input[i + 2] < key_c[2])
		{
			key_n[2] = (input[i + 2] + ALPHABET) - key_c[2];
		}
		else
		{
			key_n[2] = input[i + 2] - key_c[2];
		}
		
		if(input[i + 3] < key_c[3])
		{
			key_n[3] = (input[i + 3] + ALPHABET) - key_c[3];
		}
		else
		{
			key_n[3] = input[i + 3] - key_c[3];
		}
#if compile == 4
		printf("func_get_key4 %d回目のループ key[0] = %d key[1] = %d key[2] = %d key[3] = %d\n", i, key_n[0], key_n[1], key_n[2], key_n[3]);
#endif
		
		if((key_n[0] == key_n[1]) && (key_n[0] == key_n[2]) && (key_n[0] == key_n[3]))
		/*
		key_n[0],key_n[1],key_n[2],key_n[3]の4つが全て同値である場合{}内の処理を行う
		*/
		{
#if compile == 4
			printf("if((key_n[0] == key_n[1]) && (key_n[0] == key_n[2]) && (key_n[0] == key_n[3])) are true\n");
#endif
			if((i == 0) && ((97 >= input[i + 4]) || (122 <= input[i + 4])))
			/*
			iの値が0の場合は前の要素を参照できないのでここで処理を分岐
			要素番号i+3の要素が文字以外である場合
			*/
			{
#if compile == 4 //デバッグ用,if((i == 0) && ((97 >= input[i + 4]) || (122 <= input[i + 4])))が真である場合動作
				printf("return TRUE\n");
#endif
				return TRUE; //鍵取得成功
			}
			else if(((97 >= input[i - 1]) || (122 <= input[i - 1])) && ((97 >= input[i + 4]) || (122 <= input[i + 4])))
			/*
			iの値が0以外の場合ではi-1の要素とi+4の要素を参照する必要がある
			2つの要素がアルファベットでない場合はTRUEを返す
			*/
			{
#if compile == 4 
				/*
				デバッグ用,else if(((97 >= input[i - 1]) && (122 <= input[i - 1])) && ((97 >= input[i + 4]) && (122 <= input[i + 4])))
				が真である場合に動作
				*/
				printf("return TRUE\n");
#endif
				return TRUE; //鍵取得成功
			}
		}
	}
#if compile == 4
	printf("return FALSE\n");
#endif
	return FALSE; //鍵取得失敗
}
//------------------------------------------------------------------------------------------------------------------------
void func_decord(char array[], char result[], int key)
{
#if compile == 5
	printf("array = %s\n key = %d\n", array, key);
#endif
	int i = 0;
	for(i = 0; array[i] != 0x00; i++)
	{
#if compile == 5
		printf("array[%d] = %d ", i, array[i]);
#endif
		if((97 <= array[i]) && (122 >= array[i]))
		{
			if(97 > (array[i] - key))
			{
				result[i] = array[i] + ALPHABET - key;
#if compile == 5
				printf("result[%d] = %d = %d + %d - %d\n", i, result[i], array[i], ALPHABET, key);
#endif
			}
			else
			{
				result[i] = array[i] - key;
#if compile == 5
				printf("result[%d] = %d = %d + %d - %d\n", i, result[i], array[i], ALPHABET, key);
#endif
			}
		}
		else
		{
			result[i] = array[i];
#if compile == 5
			printf("result[%d] = %d array[%d] = %d\n", i, result[i], i, array[i]);
#endif
			continue;
		}
	}
}
//------------------------------------------------------------------------------------------------------------------------
void func_output(char array[])
{
	int i = 0;
	for(i = 0; array[i] != 0x00; i++)
	{
		if(array[i + 1] != 0x00)
		{
			printf("%c", array[i]);
		}
		else
		{
			printf("%c\n", array[i]);
		}
	}
	//printf("%s\n", array);
}

Measured memory_bytes: 524