{x}
blog image

Guess the Word

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 Explanation for Guess the Word

This problem requires finding a secret word from a list of words using a limited number of guesses. The Master.guess(word) function provides feedback on the guess, indicating the number of exact matches (both character and position). We can't use brute force due to the constraint on the number of guesses. A more efficient strategy is needed.

The optimal solution leverages a minimax approach, aiming to minimize the maximum number of remaining candidates in the worst-case scenario after each guess. While a completely optimal solution would be computationally expensive for large word lists, a heuristic approach provides a good balance of efficiency and accuracy.

Algorithm:

  1. Initialization: Begin with the entire list of words (words) as candidates.

  2. Iterative Guessing: Repeat the following steps until the secret word is found or the allowed guesses are exhausted:

    • Candidate Selection: Choose a word from the current candidate list. The best choice is the word that minimizes the maximum number of remaining candidates after comparing it to all other candidates in the list (this is the minimax aspect, though calculating it perfectly for all possible scenarios would be computationally expensive). A heuristic simplification is often used here.
    • Guess and Feedback: Call Master.guess(selected_word) to get the number of exact matches.
    • Candidate Reduction: Update the candidate list by removing any word that doesn't match the feedback (number of exact matches) with the chosen word.
  3. Termination: If the secret word is found (Master.guess returns 6), return success. If the allowed guesses are exhausted, return failure.

Heuristic for Word Selection: Finding the absolute minimax word is computationally expensive. Instead, a common heuristic is to select a word from the candidate list that has the highest number of unique characters. This aims to maximize the information gained from each guess, as a word with many unique characters will likely filter out more candidates when compared against the guess.

Code (Python):

def findSecretWord(words, master):
    """
    Finds the secret word using the Master.guess function.
 
    Args:
        words: A list of candidate words.
        master: The Master object with the guess function.
 
    Returns:
        None. Prints success or failure message.
    """
    candidates = words
    guesses_left = 10  # Adjust based on allowedGuesses
 
    while guesses_left > 0 and candidates:
        # Heuristic: Choose a word with many unique characters
        best_word = max(candidates, key=lambda word: len(set(word)))
 
        matches = master.guess(best_word)
 
        if matches == 6:
            print("You guessed the secret word correctly.")
            return
 
        new_candidates = []
        for word in candidates:
            if match_count(best_word, word) == matches:
                new_candidates.append(word)
        candidates = new_candidates
        guesses_left -= 1
 
    print("Either you took too many guesses, or you did not find the secret word.")
 
def match_count(word1, word2):
    """Counts exact matches between two words."""
    count = 0
    for i in range(len(word1)):
        if word1[i] == word2[i]:
            count += 1
    return count
 

Time Complexity: The time complexity is difficult to express precisely due to the heuristic and the variability of candidate reduction in each iteration. In the worst case, each guess could eliminate only a few candidates, leading to a complexity that approaches O(N^2), where N is the number of words. However, in practice, the heuristic usually leads to faster convergence.

Space Complexity: O(N), where N is the number of words, to store the candidate list.

Note: The provided Python code uses a simple heuristic for word selection. More sophisticated heuristics or more computationally intensive minimax algorithms could improve performance in some cases, but they would also increase the time complexity. The focus here is on providing a clear, relatively efficient, and easy-to-understand solution.