From 63647f82700c49bc50ca155be70d820b9737af2f Mon Sep 17 00:00:00 2001 From: Cameron Blankenbuehler Date: Fri, 19 Aug 2022 17:45:40 -0400 Subject: [PATCH] Add boggler_utils.py Inlcludes WordTree and WordNode(s) for structuring dictionary data --- boggler_utils.py | 74 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 boggler_utils.py diff --git a/boggler_utils.py b/boggler_utils.py new file mode 100644 index 0000000..285ff31 --- /dev/null +++ b/boggler_utils.py @@ -0,0 +1,74 @@ +'''Dictionary Utils''' +class WordNode: + '''A node that indicates a single letter in a word. Used to populate a WordTree''' + def __init__(self, char: str, is_word: bool, children: dict['WordNode'] = None) -> 'WordNode': + self.char = char + self.is_word = is_word + self.children = children if children is not None else {} + + def add_child_node(self, node): + '''Add child node to `children` dictionary, indexed by the nodes' `char`''' + self.children[node.char] = node + + def __str__(self): + return f"WordNode: {self.char}, {self.is_word}, {self.children}" + + def __repr__(self): + return self.__str__() + +class WordTree: + '''A tree populated by WordNode(s) to complete words from a given wordlist''' + def __init__(self, wordlist: list[str], alphabet: str, max_word_len: int = 16) -> WordNode: + + self.wordlist = wordlist + self.max_word_len = max_word_len + # Generate root nodes for each letter of the alphabet + self.tree = {} + for char in alphabet: + self.tree[char] = WordNode(char, False) + + # Populate tree from wordlist + for word in wordlist: + self.__insert_word(word) + + def __str__(self): + return ", ".join(self.wordlist) + + def __insert_word(self, word): + curr_node = self.tree[word[0]] + # print(word[0]) + for letter in word[1:self.max_word_len]: + # Insert new WordNode for each letter that doesen't already exist in the tree + if letter not in curr_node.children: + curr_node.children[letter] = WordNode(letter, False) + # print(letter) + curr_node = curr_node.children[letter] + # Mark the last node of the word + curr_node.is_word = len(word) <= self.max_word_len + print(f"Added: {word[:self.max_word_len]}") + + def search(self, word) -> bool: + '''Return True if a given word is in the tree otherwise return False''' + curr_node = self.tree[word[0]] + for char in word[1:]: + if char not in curr_node.children: + return False + + curr_node = curr_node.children[char] + + return curr_node.is_word + + +if __name__ == "__main__": + tree = WordTree(['anger', + 'ape', + 'bigger', + 'bit', + 'bite', + 'biter', + 'cart', + 'cast', + ], "abcdefghijklmnopqrstuvwxyz") + print(tree) + print(tree.search('cast')) + print(tree.search('hype'))