leetcode - 843. Guess the Word

Description

You are given an array of unique strings words where words[i] is six letters long. One word of words was chosen as a secret word.

You are also given the helper object Master. You may call Master.guess(word) where word is a six-letter-long string, and it must be from words. Master.guess(word) returns:

  • -1 if word is not from words, or
  • an integer representing the number of exact matches (value and position) of your guess to the secret word.

There is a parameter allowedGuesses for each test case where allowedGuesses is the maximum number of times you can call Master.guess(word).

For each test case, you should call Master.guess with the secret word without exceeding the maximum number of allowed guesses. You will get:

  • “Either you took too many guesses, or you did not find the secret word.” if you called Master.guess more than allowedGuesses times or if you did not call Master.guess with the secret word, or
  • “You guessed the secret word correctly.” if you called Master.guess with the secret word with the number of calls to Master.guess less than or equal to allowedGuesses.

The test cases are generated such that you can guess the secret word with a reasonable strategy (other than using the bruteforce method).

Example 1:

Input: secret = "acckzz", words = ["acckzz","ccbazz","eiowzz","abcczz"], allowedGuesses = 10
Output: You guessed the secret word correctly.
Explanation:
master.guess("aaaaaa") returns -1, because "aaaaaa" is not in wordlist.
master.guess("acckzz") returns 6, because "acckzz" is secret and has all 6 matches.
master.guess("ccbazz") returns 3, because "ccbazz" has 3 matches.
master.guess("eiowzz") returns 2, because "eiowzz" has 2 matches.
master.guess("abcczz") returns 4, because "abcczz" has 4 matches.
We made 5 calls to master.guess, and one of them was the secret, so we pass the test case.

Example 2:

Input: secret = "hamada", words = ["hamada","khaled"], allowedGuesses = 10
Output: You guessed the secret word correctly.
Explanation: Since there are two words, you can guess both.

Constraints:

1 <= words.length <= 100
words[i].length == 6
words[i] consist of lowercase English letters.
All the strings of wordlist are unique.
secret exists in words.
10 <= allowedGuesses <= 30

Solution

Build a map, assume the word is the secret word, then calculate the matching count with every other words. After building the map, randomly pick one to start, by guessing we will know the potential words, and we just need to get the common sets of all possible candidates.

Code

# """
# 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:
        def get_matching_cnt(word1: str, word2: str) -> int:
            res = 0
            for i in range(len(word1)):
                if word1[i] == word2[i]:
                    res += 1
            return res
        # preprocess to get matching map
        # {index: {matching_cnt: [index1, index2, ...]}}
        matching = {}
        for i in range(len(words)):
            matching[i] = {}
            for j in range(7):
                matching[i][j] = []
        for i in range(len(words)):
            for j in range(i + 1, len(words)):
                matching_cnt = get_matching_cnt(words[i], words[j])
                matching[i][matching_cnt].append(j)
                matching[j][matching_cnt].append(i)
        # start by random index
        index = random.choice(range(len(words)))
        matching_from_guess = master.guess(words[index])
        if matching_from_guess == 6:
            return
        candidates = matching[index][matching_from_guess]
        visited = set([index])
        while len(candidates) > 1:
            index = random.choice(candidates)
            matching_from_guess = master.guess(words[index])
            if matching_from_guess == 6:
                return
            visited.add(index)
            next_candidates = matching[index][matching_from_guess]
            new_candidates = list(set(candidates) & set(next_candidates) - visited)
            candidates = new_candidates
        master.guess(words[candidates[0]])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值