Katkat

Find a secret word using match feedback

AtlassianMachine Learning Engineer · Onsite

Last updated

Design an optimal querying strategy to identify a secret word from a candidate vocabulary using exact-match character feedback under a strict query budget.

Problem Statement

You are given a list of unique words of equal length, wordlist, along with an interactive oracle object master of type Mastermind.

One word from wordlist is designated as the secret. The oracle provides a single method:

  • master.guess(word: str) -> int: Returns the number of exact matches (same character at the same position) between word and the secret. If word is not in wordlist, it returns -1.

Your task is to find and return the secret word using at most 10 calls to master.guess. If your strategy exhausts the query limit without identifying the secret, the test fails.

Function Interface

class Mastermind:
    def guess(self, word: str) -> int:
        pass

def find_secret_word(wordlist: list[str], master: Mastermind) -> str:
    pass

Inputs and Outputs

  • wordlist: A list of strings where each string has length 6 consisting of lowercase English letters.
  • master: An instance of Mastermind initialized with secret.
  • Returns: The secret word as a string.

Constraints

  • 2 <= len(wordlist) <= 100
  • len(word) == 6 for all word in wordlist
  • All words in wordlist are unique.
  • secret is guaranteed to be in wordlist.
  • You may call master.guess at most 10 times per test case.

Examples

Example 1

Input:
wordlist = ["acckzz", "ccbazz", "eiowzz", "abcczz"]
secret = "acckzz"

Execution:
master.guess("eiowzz") -> returns 2 (matches at positions 4 and 5: 'z', 'z')
Candidates remaining whose similarity to "eiowzz" is 2: ["acckzz", "ccbazz", "abcczz"]
master.guess("acckzz") -> returns 6

Output: "acckzz"
Explanation: "acckzz" matches all 6 characters of the secret.

Example 2

Input:
wordlist = ["hamlet", "kitten", "banner", "mantle"]
secret = "banner"

Execution:
master.guess("hamlet") -> returns 1 (matches 'a' at index 1)
Candidates filtered: only words with exactly 1 match to "hamlet" are retained.
master.guess("banner") -> returns 6

Output: "banner"

Edge Cases to Consider

  • Zero matches: A score of 0 is informative; eliminate all candidates that share any characters at identical indices with the guessed word.
  • Multiple disjoint clusters: When candidates have very low pairwise overlap, choosing an arbitrary candidate might yield zero matches repeatedly unless chosen strategically.
  • Candidate elimination: When a guess returns k < 6, prune all words w in the remaining candidate pool where match(guess, w) != k.

Hints

Hint 1

Every guess provides an exact match count k; any word in your remaining candidate set that does not have exactly k matches with your guess can be eliminated.

Hint 2

A naive random choice can leave large candidate pools in the worst case; consider a minimax strategy where you choose the word that minimizes the maximum possible remaining candidate set.

Hint 3

For each candidate w, calculate how the other candidates would be partitioned across match scores 0 through 6, and pick w that minimizes the largest bucket.

Follow-up questions

  • How would you scale your search strategy if the word length were 20 and the candidate list contained 1,000,000 words?
  • How would your approach change if the oracle had a 5% chance of returning a match count that is off by plus or minus 1?
  • Instead of minimax, how could Shannon entropy be used to select the candidate that maximizes expected information gain?