/**
* // This is the Master's API interface.
* // You should not implement it, or speculate about its implementation
* class Master {
* public:
* int guess(string word);
* };
*/
class Solution {
public:
void findSecretWord(vector<string>& wordlist, Master& master) {
}
};
# """
# This is Master's API interface.
# You should not implement it, or speculate about its implementation
# """
# class Master:
# def guess(self, word: str) -> int:
class Solution:
def findSecretWord(self, words: List[str], master: 'Master') -> None:
m = defaultdict(list)
for word1 in words:
for word2 in words:
diff = 0
for i in range(len(word1)):
if word1[i] != word2[i]:
diff += 1
m[word1, diff].append(word2)
s = set(words)
while len(s) > 0:
same = master.guess(list(s)[0])
if same == 6: return
s &= set(m[list(s)[0], 6 - same])
# """
# This is Master's API interface.
# You should not implement it, or speculate about its implementation
# """
# class Master:
# def guess(self, word: str) -> int:
'''
方法 1:启发式极小化极大算法
显然,可行单词列表中的单词越少越好。如果数据随机,那么我们可以认定这个情况是普遍的。
现在,利用极小化极大算法猜测可行的单词列表。如果我们开始有 N 个单词,我们通过迭代去选择可行单词。
算法
存储 H[i][j] 为 wordlist[i] 和 wordlist[j] 单词匹配数。每次猜测要求之前没有猜过,
按照上面的说法实现极小化极大算法,每次选择猜测的单词是当前可行单词中的一个。
'''
class Solution:
def findSecretWord(self, wordlist: List[str], master: 'Master') -> None:
N = len(wordlist)
self.H = [[sum(a==b for a,b in zip(wordlist[i], wordlist[j]))
for j in range(N)] for i in range(N)]
possible, path = range(N), ()
while possible:
guess = self.solve(possible, path)
matches = master.guess(wordlist[guess])
if matches == len(wordlist[0]): return
possible = [j for j in possible if self.H[guess][j] == matches]
path = path + (guess,)
def solve(self, possible, path = ()):
if len(possible) <= 2: return possible[0]
ansgrp, ansguess = possible, None
for guess, row in enumerate(self.H):
if guess not in path:
groups = [[] for _ in range(7)]
for j in possible:
if j != guess:
groups[row[j]].append(j)
maxgroup = max(groups, key = len)
if len(maxgroup) < len(ansgrp):
ansgrp, ansguess = maxgroup, guess
return ansguess