#include	<iostream>
#include	<algorithm>
#include	<vector>
#include	<fstream>
#include	<cctype>
#include	<stdexcept>

using std::vector;
using std::string;
using std::ifstream;
using std::endl;
using std::cerr;
using std::cout;
using std::invalid_argument;
using std::transform;

bool
capitalized(const string &str)
{
	string::const_iterator	it;
	for (it = str.begin(); it != str.end(); it++) 
		if (isupper(*it))
			return true;
	return false;
}

bool
ends_in_x(const string &str)
{
	return *(str.end() - 1) == 'x';
}

string
uncapitalize(const string &str)
{
	string	ret;
	string::const_iterator	it;
	for (it = str.begin(); it != str.end(); it++) 
		ret += tolower(*it);
	return ret;
}

void
read_words(const char *file, vector<string> &words)
{
	ifstream in(file);

	if (! in)
		throw invalid_argument("Invalid file \"" + string(file) + "\"");

	string word;
	while (in >> word)
		words.push_back(word);
}

void
show_words(const vector<string> &words)
{
	vector<string>::const_iterator it;
	for (it = words.begin(); it != words.end(); it++) 
		cout << *it << endl;
}

int
main()
{
	vector<string> standard;
	vector<string> custom;

	try {
		read_words("/usr/share/dict/words", standard);
		read_words("custom", custom);
	} catch (invalid_argument e) {
		cerr << e.what() << endl;
		return -1;
	}

	// Create a new vector which consists of all the strings
	// in 'standard' and all the strings in 'custom'.
	//
	vector<string> all(standard);

	copy(custom.begin(), custom.end(), back_inserter(all));
	// or equivalently...
	//       all.insert(all.end(), custom.begin(), custom.end());

	// Remove all those strings from 'all' that end in the letter 'x'.
	//
	vector<string>::iterator zap;
	zap = remove_if(all.begin(), all.end(), ends_in_x);
	all.erase(zap, all.end());

	// Create a new vector 'uncapitalized' that will contain all those
	// strings in 'all' that contain no capitalized letters.
	// Note that vector 'all' is unmodified.
	//
	vector<string> uncapitalized;
	remove_copy_if(all.begin(), all.end(), back_inserter(uncapitalized),
			capitalized);

	// Finally create a new vector 'lowercase' which contains all the
	// strings of 'all', but lowercased.
	//
	vector<string> lowercase;
	transform(all.begin(), all.end(), back_inserter(lowercase),
			uncapitalize);

	show_words(lowercase);
}
