/* Problem 4--Palinwords
   This one wasn't that bad, particularly if you knew the relevant
   string functions to make this one a bit easier. */

#include <fstream>
#include <cstring>
using namespace std;

#define MAX(a,b) ((a) > (b) ? (a) : (b))

int main (int argc, char **argv);
bool DoublePalindrome (char *s);
bool IsPalindrome (char *s, int l);
bool Exclusive (char *s, int sl, char *t, int tl);

ifstream in ("prob4.in");
ofstream out ("prob4.out");

int main (int argc, char **argv) {

 char word[21];
 while (true) {
  in >> word; //Read in word; print if it's a palinword.
  if (strcmp (word,"END")==0) return 0;
  if (DoublePalindrome (word)) out << word << endl;
 }
 return 0;
}

bool DoublePalindrome (char *s) {

 int l = strlen (s);
 for (int i = 0; i < l-2; i++) //Possible beginnings of first palindrome
  for (int j = i+2; j < l; j++) //Possible ends of first palindrome
   if (IsPalindrome (s+i,j-i+1)) //Is the first thing a palindrome?
    for (int k = i+1; k < l-2; k++) //Possible beginnings of second
     for (int m = MAX (k+2,j+1); m < l; m++) //Possible ends of second
      if (IsPalindrome (s+k,m-k+1) && //Is that a palindrome?
          Exclusive (s+i,j-i+1,s+k,m-k+1)) //Are they independent?
       return true;
 return false;
}

/* IsPalindrome checks whether a given string is a palindrome. */

bool IsPalindrome (char *s, int l) {

 for (int i = 0; i < l/2; i++)
  if (s[i] != s[l-i-1]) return false;
 return true;
}

/* Exclusive checks whether one palindrome contains the other.  Note
   that strstr is a built-in function that handles this. */

bool Exclusive (char *s, int sl, char *t, int tl) {

 char ss[21]={}, tt[21]={};
 memcpy (ss,s,sl); memcpy (tt,t,tl);
 return (strstr (ss,tt) == NULL && strstr (tt,ss) == NULL);
}
