LeetCode 843. Guess the Word
原题链接
困难
作者:
JasonSun
,
2020-01-17 00:41:29
,
所有人可见
,
阅读 582
Algorithm
- At each one of the $10$ tries, we keep filtering out the items from the list that does not fit the match number.
- The actual probability could be computed using some INSANE analytic combinatorics. I cannot think of a better method than this. It is basically asking given a randomly generated $6n$ length strings where $n\geq10,$ what are the chances that the $6$ length cuts are quite different. To calculate the probability, one would need to work out all the patterns under which $6$ length cuts are quite similar. There are some easy patterns to start with, such that all $n$ cuts have the same number of matches. The probability of this is $$\mathbb{P}(n\text{ cuts have same matchs})=\sum_{i=1}^{6}\binom{6n}{6i}\left(\frac{1}{26}\right)^{6i}\left(\frac{1}{26}\right)^{6n-6i}.$$ But this does not help much. If you have a better idea, please PM me so that I can update it.
Code
class Solution {
public:
void findSecretWord(vector<string>& wordlist, Master& master) {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<int> Unif(0, size(wordlist) - 1);
auto match = [&](const string &x, const string & y) {
int acc = 0;
for (int i = 0; i < 6; ++i)
if (x[i] == y[i])
++acc;
return acc;
};
auto solve = [&]()-> void {
auto word_filter = vector<optional<string>>(begin(wordlist), end(wordlist));
for (int i = 0; i < 10; ++i) {
const auto candidate = [&] {
const auto rand_id = [&](int self = 0) {
while (not word_filter[self])
self = Unif(gen);
return self;
}();
return word_filter[rand_id].value();
}();
const auto response = master.guess(candidate);
if (response == -1)
continue;
else {
for (int i = 0; i < size(wordlist); ++i)
if (word_filter[i] and match(word_filter[i].value(), candidate) != response)
word_filter[i].reset();
}
}
};
solve();
}
};