Example #1
0
void Dictionary::printInteractiveSuggestions(Words const& active_words, unsigned const show) const
{
	assert(!active_words.empty());
	assert(show > 0);
	vector<pair<double, Word>> suggestions;
	suggestions.reserve(active_words.size());
	puts("Suggestions:");
	{
		DividedWordList dl(wordLength());
		auto it = keys_.cbegin();
		do {
			dl.build(*this, active_words, *it);
			suggestions.push_back(make_pair(-dl.entropy(), *it));
		} while (++it != keys_.cend());
	}
	sort(suggestions.begin(), suggestions.end());
	{
		auto it = suggestions.cbegin();
		unsigned i = 0;
		do {
			printf("\t%2u: ", ++i);
			describeWord(stdout, it->second);
			putchar('\n');
		} while (++it != suggestions.cend() && i < show);
	}
	putchar('\n');
}
Example #2
0
void DividedWordList::build(Dictionary const& dictionary, Words const& ws, Word const guess)
{
	assert(size() == dictionary.wordLength() + 1);
	assert(!ws.empty());
	for (auto it = begin(); it != end(); ++it)
		it->clear();
	{
		auto it = ws.cbegin();
		do {
			unsigned const c = correct_letters(*it, guess);
			assert(c <= dictionary.wordLength());
			(*this)[c].update(dictionary, *it);
		} while (++it != ws.cend());
	}
}
Example #3
0
void Dictionary::recursiveInteractive(Words const& active_words) const
{
	if (active_words.empty()) {
		puts("No choices remain.\n");
	} else if (active_words.size() == 1) {
		fputs("Only choice remaining is: ", stdout);
		describeWord(stdout, active_words.front());
		puts("\n");
	} else {
		printf("%u choices remain", static_cast<unsigned>(active_words.size()));
		if (active_words.size() <= 5) {
			// If we're near the end, print a list
			fputs(": ", stdout);
			auto it = active_words.cbegin();
			describeWord(stdout, *it);
			do {
				fputs(", ", stdout);
				describeWord(stdout, *it);
			} while (++it != active_words.cend());
			putchar('\n');
		} else {
			puts(".");
		}
		putchar('\n');

		string cmd;
		for (;;) {
			printInteractiveSuggestions(active_words);
			fputs("Give your move in form \"<word> <result>\" like \"TAXI 2\"\n\n"
			      "> ", stdout);
			fflush(stdout);
			if (!read_uppercase_word(stdin, &cmd))
				break;	// EOF
			Word tried;
			unsigned matched;
			if (parse_move(cmd, wordLength(), &tried, &matched)) {
				DividedWordList dl(wordLength());
				dl.build(*this, active_words, tried);
				recursiveInteractive(dl[matched].choices());
				break;
			}
			puts("Invalid move.\n");
		}
	}
}
Example #4
0
void Dictionary::recursiveSolve(AbstractSolutionAcceptor * const acceptor, Words const& active_words, AnswerSequence * const runningAnswersp) const
{
	assert(!active_words.empty());
	if (active_words.size() == 1) {	// We found an end node
		acceptor->acceptSolution(*runningAnswersp, active_words.front());
	} else {
		DividedWordList dl(wordLength());
		double best_entropy = -1.0;
		Word best_word = 0;
		// Of all of the words in active_words, find the one that
		// will gives us the most even split (and thus the highest entropy)
		{
			auto it = keys_.cbegin();
			do {
				dl.build(*this, active_words, *it);
				double const entropy = dl.entropy();
				if (entropy > best_entropy) {
					best_entropy = entropy;
					best_word = *it;
				}
			} while (++it != keys_.cend());
		}
		assert(popcount32(best_word) == wordLength());
		// Now that we have found our best word, recompute the split
		dl.build(*this, active_words, best_word);
		assert(dl.entropy() == best_entropy);
		acceptor->acceptBranch(*runningAnswersp, best_word, best_entropy, dl);
		// Now recursively descend
		for (unsigned i = 0; i < wordLength() + 1; i++) {
			const WordsWithTotalChoices& wwtc = dl[i];
			if (wwtc.count() > 0) {
				runningAnswersp->push_back(i);
				recursiveSolve(acceptor, wwtc.choices(), runningAnswersp);
				runningAnswersp->pop_back();
			}
		}
	}
}
Example #5
0
LicensePos findLicense( const Words & words, const QList< Statement > & license,
	int & idx )
{
	LicensePos res{ -1, -1 };

	int firstWord = 0;

	// Find first real word.
	for( int i = 0; i < license.count(); ++i )
	{
		if( license.at( i ).type() == Statement::Word )
		{
			firstWord = i;

			break;
		}
	}

	auto first = words.cbegin();
	first += idx;

	auto it = std::find( first, words.cend(), WordWithPlace{
		license.at( firstWord ), -1, -1 } );

	while( it != words.cend() )
	{
		idx = std::distance( words.cbegin(), it );

		bool found = true;
		int wp = idx;

		for( int j = firstWord; j < license.count(); ++j )
		{
			if( license.at( j ).type() == Statement::Word )
			{
				// Skip line endings.
				while( wp < words.count() &&
					words.at( wp ).m_st.type() == Statement::LineEnding )
				{
					++wp;
				}

				if( wp >= words.count() )
				{
					found = false;

					break;
				}

				if( license.at( j ).word() != words.at( wp ).m_st.word() )
				{
					found = false;

					break;
				}
			}
			else if( license.at( j ).type() == Statement::SkipLine )
			{
				bool skipped = false;

				if( wp < words.count() &&
					words.at( wp ).m_st.type() == Statement::LineEnding )
				{
					++wp;

					skipped = true;
				}

				while( wp < words.count() &&
					words.at( wp ).m_st.type() != Statement::LineEnding )
				{
					++wp;

					skipped = true;
				}

				if( ( wp >= words.count() && j < license.count() - 1 ) ||
					!skipped )
				{
					found = false;

					break;
				}

				if( wp < words.count() - 1 &&
					words.at( wp ).m_st.type() == Statement::LineEnding )
						--wp;
			}
			else if( license.at( j ).type() == Statement::SkipWord )
			{
				// Skip line endings.
				while( wp < words.count() &&
					words.at( wp ).m_st.type() == Statement::LineEnding )
				{
					++wp;
				}
			}

			if( j < license.count() - 1 )
				++wp;
		}

		// If license was found.
		if( found )
		{
			if( wp == words.count() )
				--wp;

			int x = idx;

			if( firstWord > 0 )
			{
				for( int i = firstWord - 1; i >= 0; --i )
				{
					if( license.at( i ).type() == Statement::SkipWord )
					{
						while( x > 0 &&
							words.at( x - 1 ).m_st.type() != Statement::Word )
						{
							--x;
						}

						--x;
					}
					else if( license.at( i ).type() == Statement::SkipLine )
					{
						--x;

						while( x > 0 &&
							words.at( x - 1 ).m_st.type() != Statement::LineEnding )
						{
							--x;
						}
					}
				}

				if( x < 0 )
					x = 0;
			}

			res = { ( license.at( 0 ).type() == Statement::SkipFirstSpaces ||
				license.at( 0 ).type() == Statement::SkipLine ?
					words.at( x ).m_posWithSpaces : words.at( x ).m_pos ),
				words.at( wp ).m_pos + words.at( wp ).m_st.word().length() };

			idx = wp + 1;

			break;
		}

		if( wp >= words.count() )
			break;

		it = std::find( ++it, words.cend(), WordWithPlace{
			license.at( firstWord ), -1, -1 } );
	}

	return res;
} // findLicense