int scrabble_search_test(const char* filename)
{
	long result = errors_counter();
	trivial_scrabble_test();
	exhaustive_scrabble_test(filename);
	return errors_counter() - result;
}
int exhaustive_scrabble_test(const char* filename)
{
	long result = errors_counter();
	// note that dictsize*keys*3 tests are performed
	size_t DICTSIZE = 10000, KEYS = 10;
	typedef std::vector<std::string> Dictionary;
	extern size_t fill_dictionary(const char*, Dictionary&, size_t, size_t = 0);
	Dictionary dictionary;
	size_t longest_in_file = fill_dictionary(filename, dictionary, DICTSIZE);
	std::random_shuffle(dictionary.begin(), dictionary.end());

	ScrabbleTst names;

	Dictionary::iterator dit;
	for (dit = dictionary.begin(); dit != dictionary.end(); dit += 4) {
		const std::string& name(*dit);
		names[name] = name.c_str();
	}

	int skip = dictionary.size() / KEYS;
	for(dit = dictionary.begin() + skip; dit != dictionary.end(); dit += skip)
	{
		std::string name(*dit);
		std::sort(name.begin(), name.end());
		for (int jokercount = 0; jokercount < 3; ++jokercount) {
			ScrabbleTst::search_results_list matchresults = names.create_search_results();
			names.combinatorial_search(name, std::back_inserter(matchresults), jokercount);
			//if (matchresults.size() == 0)
			//	std::cout << "couldn't find " << name << '\n';
			BOOST_CHECK(matchresults.size() != 0);
			ScrabbleTst matches;
			ScrabbleTst matchcount;
			size_t prevsize = 0;
			for (size_t i = 0; i != matchresults.size(); ++i) {
				std::string mcopy(matchresults[i].key());
				matchcount[mcopy] = mcopy.c_str();
				if (matchcount.size() > prevsize) {
					BOOST_CHECK(check_scrabble_found(name, mcopy, jokercount));
					++prevsize;
				}
				else {
					std::cout << "scrabble found duplicate " << mcopy << "\n";
				}
				std::sort(mcopy.begin(), mcopy.end());
				matches[mcopy] = mcopy.c_str();
			}
			// check for duplicates
			scrabble_findcount += matchresults.size();
			scrabble_duplicates += matchresults.size() - matchcount.size();
			BOOST_CHECK(matchcount.size() == matchresults.size());
			BOOST_CHECK(check_scrabble_missed(names, matches, jokercount));
		}
	}
	//std::cout << "scrabble duplicate matches " << scrabble_duplicates << " of " << scrabble_findcount << "\n";

	return errors_counter() - result;
}
int trivial_scrabble_test()
{
	long result = errors_counter();

	typedef containers::ternary_tree<std::string, const char*> Tst;
	Tst names;
	names["ABCD"] = "ABCD";
	names["Abcd"] = "Abcd";
	names["ABcd"] = "ABcd";
	names["aBCd"] = "aBCd";
	names["abc"] = "abc";
	names["abcde"] = "abcde";
	names["bcd"] = "bcd";
	names["abCD"] = "abCD";
	names["abCd"] = "abCd";
	names["AbcD"] = "AbcD";
	names["ABcD"] = "ABcD";
	names["aBCD"] = "aBCD";
	names["abCDE"] = "abCDE";
	names["abCDd"] = "abCDd";
	names["abCcd"] = "abCcd";
	names["bcdc"] = "bcdc";
	names["aab"] = "aab";

	Tst::search_results_list matches = names.create_search_results();
	typedef Tst::search_results_list::iterator ResultIter;

	int i = 0;
	std::string s("abcde");
	names.combinatorial_search(s, std::back_inserter(matches));
	BOOST_CHECK(matches.size() == 3);
	matches.clear();
	std::random_shuffle(s.begin(), s.end());
	names.combinatorial_search(s, std::back_inserter(matches));
	BOOST_CHECK(matches.size() == 3);
	// with wildcards
	matches.clear();
	std::random_shuffle(s.begin(), s.end());
	names.combinatorial_search(s, std::back_inserter(matches), 1);
	BOOST_CHECK(matches.size() == 8);
	//for (ResultIter rit = matches.begin(); rit != matches.end(); ++rit, ++i)
	//	std::cout << i << ": " << **rit << "\n";
	matches.clear();
	s.append(s);
	std::random_shuffle(s.begin(), s.end());
	names.combinatorial_search(s, std::back_inserter(matches));
	BOOST_CHECK(matches.size() == 5);
	//for (ResultIter rit = matches.begin(); rit != matches.end(); ++rit, ++i)
	//	std::cout << i << ": " << **rit << "\n";
	return errors_counter() - result;
}
Esempio n. 4
0
int check_empty(containers::ternary_tree<std::basic_string<CharT>, DataT>& tst)
{
	typedef containers::ternary_tree<std::basic_string<CharT>, DataT> Tst;

	long result = errors_counter();
	BOOST_CHECK(tst.empty());
	BOOST_CHECK(tst.node_count() == 0);
	BOOST_CHECK(tst.item_count() == 0);

	Tst::iterator i2(tst.begin());
	BOOST_CHECK(i2 == tst.end());

	return errors_counter() - result;
}
Esempio n. 5
0
int iteration_quickcheck(Tst& tst, size_t expectcount,
						 CharT* unexpected = 0)
{
	long result = errors_counter();
	size_t count = 0;
	Tst::iterator first = tst.begin();
	Tst::iterator last = tst.end();
	const char *last_value = 0;
	while(first != last) {
		if (first.key() != *first)
			std::cout << first.key() << " != " << *first << '\n';
		BOOST_CHECK(first.key() == *first);
		last_value = first.value();
		if (unexpected)
			BOOST_CHECK(first.key() != unexpected);
		++first;
		count++;
	}
	BOOST_CHECK(first == tst.end());
	if (count != expectcount)
		std::cout << count << " < " << expectcount << '\n';
	BOOST_CHECK(count == expectcount);

	count = 0;
	first = --tst.end();
	Tst::const_reverse_iterator rit = tst.rbegin();
	BOOST_CHECK(*first == last_value);
	last = tst.end();
	while(first != last) {
		if (first.key() != *first)
			std::cout << first.key() << " != " << *first << '\n';
		if (*first != *rit)
			std::cout << *first << " != " << *rit << '\n';
		BOOST_CHECK(first.key() == *first);
		BOOST_CHECK(*first == *rit);
		if (unexpected)
			BOOST_CHECK(first.key() != unexpected);
		--first;
		++rit;
		count++;
	}
	BOOST_CHECK(rit == const_cast<const Tst&>(tst).rend());
	if (count != expectcount)
		std::cout << count << " < " << expectcount << '\n';
	return errors_counter() - result;
}
Esempio n. 6
0
inline void
report_error( const char* msg, const char* file, int line, const_string func_name, bool is_msg = false )
{
    ++errors_counter();
    std::cerr << file << "(" << line << "): ";

    if( is_msg )
        std::cerr << msg;
    else
        std::cerr << "test " << msg << " failed";

    if( func_name != "(unknown)" )
        std::cerr << " in function: '" << func_name << "'";

    std::cerr << std::endl;
}
Esempio n. 7
0
int levenshtein_search_test()
{
	long result = errors_counter();

	// Create a tree with known levenshtein count = 100
	std::string b0("abcdefjklmn");
	int testcount = 3;
	while ( testcount ) {
		std::random_shuffle(b0.begin(), b0.end());
		int baselen = (int)b0.size();
		typedef containers::ternary_tree<std::string, std::string> Tst;
		Tst names;
		int L1count = 0, L2count = 0, L3count = 0, L4count = 0;
		for (int i = 0; i < baselen; i++)
		{
			std::string s1(b0);
			mutate(s1, i);
			if (names.insert(std::make_pair(s1, s1)).second)
				L1count++;
			for (int j = 0; j < (int)s1.size(); j++)
			{
				if (j == i)
					continue;
				std::string s2(s1);
				mutate(s2, j);
				if (names.insert(std::make_pair(s2, s2)).second)
					L2count++;
				for (int k = 0; k < (int)s2.size(); k++)
				{
					if (abs(k - j) <= 1 || abs(k - i) <= 1)
						continue;
					std::string s3(s2);
					mutate(s3, k);
					//if (s3.size() < s2.size() && s3.size() == s1.size())
					//	continue;
					//if (names.insert(std::make_pair(s3, s3)).second)
					//	L3count++;
					for (int m = 2; m < (int)s3.size() - 2; m++)
					{
						if (abs(m - j) <= 2 || abs(m - i) <= 2 || abs(m - k) <= 2)
							continue;
						std::string s4(s3);
						mutate(s4, m);
						if (m + 1 >= (int)s4.size())
							continue;
						mutate(s4, m + 1);
						if (m - 1 < 0)
							continue;
						mutate(s4, m - 1);
						if (m + 2 >= (int)s4.size())
							continue;
						mutate(s4, m + 2);
						if (m - 2 < 0)
							continue;
						mutate(s4, m - 2);
						if (abs((int)s4.size() - (int)b0.size()) < 2) {
							s4.insert(rand()%s4.size(), 1, 'Z');
							s4.insert(rand()%s4.size(), 1, 'Z');
						}
						if (names.insert(std::make_pair(s4, s4)).second)
							L4count++;
					}
				}
			}
		}

		if (names.size() != L1count + L2count + L3count + L4count) {
			std::cout << "levenshtein tree name collision, try again";
			continue;
		}
		Tst::search_results_list results = names.create_search_results();
		typedef Tst::search_results_list::iterator ResultsIter;
		names.levenshtein_search(b0, std::back_inserter(results), 2);
		if (results.size() != L1count + L2count + L3count)
		{
			Tst found;
			for (ResultsIter rit = results.begin(); rit != results.end(); ++rit)
				found[**rit] = **rit;
			BOOST_CHECK(found.size() == L1count + L2count); // + L3count);
			std::cout << "\nSearch " << b0 //<< ", L-count: " << names.levenshtein_search_count
					<< ", found " << results.size() << " strings";
			std::cout << " (" << found.size() << " in " << found.node_count() << " nodes)\n";
			if (found.size() != L1count + L2count) { // + L3count) {
				Tst::iterator fit = found.begin();
				for (Tst::iterator nit = names.begin(); nit != names.end(); ++nit)
				{
					if (fit != found.end() && *nit == *fit) {
						std::cout << *nit << "\n";
						++fit;
					}
					else
						std::cout << *nit << " ###\n";
				}
			//	std::cout << "full-frontal:\n";
			//	for (ResultsIter rit = results.begin(); rit != results.end(); ++rit)
			//		std::cout << **rit << "\n";
			}
		}
		testcount--;
	}
	return errors_counter() - result;
}
Esempio n. 8
0
int hamming_search_test(const char* filename)
{
	long result = errors_counter();

	typedef containers::ternary_tree<std::string, const char*> Tst;
	Tst names;
	names["ABCD"] = "ABCD";
	names["Abcd"] = "Abcd";
	names["ABcd"] = "ABcd";
	names["aBCd"] = "aBCd";
	names["abc"] = "abc";
	names["abcde"] = "abcde";
	names["bcd"] = "bcd";
	names["abCD"] = "abCD";
	names["abCd"] = "abCd";
	names["AbcD"] = "AbcD";
	names["ABcD"] = "ABcD";
	names["aBCD"] = "aBCD";
	names["abCDE"] = "abCDE";
	names["abCDd"] = "abCDd";
	names["abCcd"] = "abCcd";
	names["bcdc"] = "bcdc";
	names["aab"] = "aab";

	// hamming_search(2): ABcd, AbcD, Abcd, aBCd, abCD, abCd, abc, abcde
	// levenshtein_search(2): hamming + abCDd, abCcd bcd, bcdc

	Tst::search_results_list matches = names.create_search_results();
	typedef Tst::search_results_list::iterator ResultIter;

	//names.levenshtein_search_count = 0;
	names.levenshtein_search("abcd", std::back_inserter(matches), 2);
	//std::cout << "l-count: " << names.levenshtein_search_count << "\n";
	//names.levenshtein_search_count = 0;
	BOOST_CHECK(matches.size() == 12);
	if (matches.size() != 12)
	{
		// compare with DDJ
		{
			Tptr root = 0;
			for (Tst::iterator it = names.begin(); it != names.end(); ++it) {
				insertstr = (char*)*it;
				root = insert2(root, insertstr);
			}
			nearsearch(root, "abcd", 2);
			std::cout << "DDJ nearsearch abcd:\n";
			for (int i = 0; i != srchtop; i++)
				std::cout << srcharr[i] << "\n";
			std::cout << "\n";
			cleanup2(root);
		}
		int i = 0;
		for (ResultIter rit = matches.begin(); rit != matches.end(); ++rit, ++i) {
			std::cout << **rit << " = " << (*rit).key();
			std::cout /*<< " = " << matches[i].key()*/ << "\n";
		}
	}

	typedef std::vector<std::string> Dictionary;
	extern size_t fill_dictionary(const char*, Dictionary&, size_t, size_t = 0);
	Dictionary dictionary;
	size_t longest_in_file = fill_dictionary(filename, dictionary, 300);
	std::random_shuffle(dictionary.begin(), dictionary.end());

	names.clear();

	Dictionary wildnames;
	// Add names with mini-variations
	long zeroes = 0;
	Dictionary::iterator dit;
	for (dit = dictionary.begin(); dit != dictionary.end(); ++dit) {
		const std::string& name(*dit);
		std::string namecopy(*dit);
		names[namecopy] = name.c_str();
		std::string searchstr(name);
		for (int i = 0; i < 5; ++i) {
			int where = rand() % name.size();
			// make string with ? at place of changed char
			if (searchstr[where] == '?')
				continue;
			searchstr[where] = '?';
			wildnames.push_back(searchstr);
			char c = (char)rand();
			if (!c) zeroes++;
			namecopy[where] = c;
			names[namecopy] = name.c_str();
		}
	}

	for(dit = wildnames.begin(); dit != wildnames.end(); ++dit) {
		const std::string& name(*dit);
		for (int diff = 1; diff != 3; ++diff) {
			Tst::search_results_list matchresults = names.create_search_results();
			names.hamming_search(name, std::back_inserter(matchresults), diff);
			//if (matchresults.size() == 0)
			//	std::cout << "couldn't find " << name << '\n';
			//BOOST_CHECK(found == matchresults.size());
			for (size_t i = 0; i != matchresults.size(); ++i)
				BOOST_CHECK(check_hamming_match(matchresults[i].key(), name, diff));
		}
	}

	return errors_counter() - result;
}
Esempio n. 9
0
int basic_insertion_test()
{
	long result = errors_counter();

	typedef containers::ternary_tree<std::basic_string<CharT>, int> Tst;
	Tst tst;

	const char* strings[] = { "\0", "aa", "aab", "aac", "add", "aee", "bab" };
	widen<CharT> w;

	// Construction postconditions
	check_empty(tst);

	// Standard insert()
	tst.insert(std::make_pair(w(strings[1]), 1));
	tst.insert(std::make_pair(w(strings[5]), 5));

	std::pair<std::basic_string<CharT>, int> inval(w(strings[3]), 3);
	std::pair<Tst::iterator, bool> vr = tst.insert(inval);
	BOOST_CHECK(vr.first != tst.end());
	BOOST_CHECK(vr.second == true);
	vr = tst.insert(inval);
	BOOST_CHECK(vr.first != tst.end());
	BOOST_CHECK(vr.second == false);

	BOOST_CHECK((*tst.find(w(strings[1]))) == 1);
	BOOST_CHECK((*tst.find(w(strings[3]))) == 3);
	BOOST_CHECK((*tst.find(w(strings[5]))) == 5);

	BOOST_CHECK(tst.item_count() == 3);
	BOOST_CHECK(tst.total_key_length() == 3*3-1);

	// In present version, no reassignment
	tst.insert(std::make_pair(w(strings[1]), 4));
	BOOST_CHECK((*tst.find(w(strings[1]))) == 1);
	BOOST_CHECK(tst.item_count() == 3);
	BOOST_CHECK(tst.total_key_length() == 3*3-1);

	// reference_proxy insert()
	tst[w(strings[2])] = 2;
	tst[w(strings[6])] = 6;
	tst[w(strings[4])] = 4;
	BOOST_CHECK(tst[w(strings[2])] == 2);
	BOOST_CHECK(tst[w(strings[4])] == 4);
	BOOST_CHECK(tst[w(strings[6])] == 6);

	BOOST_CHECK(tst.item_count() == 6);
	BOOST_CHECK(tst.total_key_length() == 6*3-1);

	// Now do reassignment
	tst[w(strings[1])] = 7;
	BOOST_CHECK((*tst.find(w(strings[1]))) == 7);  //1);
	tst[w(strings[1])] = 1;

	// iterator used to check sort order of strings
	Tst::const_iterator it(tst.begin());
	int expect_val = 1;
	while (it != tst.end()) {
		Tst::value_type val = *it;
		// string == "a", "b" etc
		BOOST_CHECK(expect_val == 1 || it.key().size() == 3);
		BOOST_CHECK(it.key() == w(strings[expect_val]));
		// value is 1, 2 etc
		BOOST_CHECK(val == expect_val++);
		++it;
	}
	BOOST_CHECK(expect_val == int(tst.item_count() + 1));

	// Test clear() postconditions
	tst.clear();

	check_empty(tst);

	return errors_counter() - result;
}