def _dfs_visit( cube: Tuple[int, int], grid: List[List[str]], word_list: pygtrie.Trie, word: str, cubes_visited: Set[Tuple[int, int]], ) -> Set[str]: """ Visit the next state in a depth-first search for words in the letter grid. :param Tuple[int, int] cube: grid indices of a letter cube :param List[List[str]] grid: a grid of letter cubes to search :param pygtrie.Trie word_list: a Trie containing all valid words :param str word: a string of letters representing the current search path :param Set[Tuple[int, int]] cubes_visited: set of cube indices already visited :return: set of valid words found from the current search state :rtype: Set[str] """ i, j = cube # Capitalize all words word += grid[i][j].upper() if not word_list.has_node(word): return set() words_found = {word} if word_list.has_key(word) and len(word) > 2 else set() neighbors = _get_neighboring_cubes(cube, grid, cubes_visited) neighboring_words = [ _dfs_visit(n, grid, word_list, word, cubes_visited.union({cube})) for n in neighbors ] return reduce(lambda x, y: x.union(y), neighboring_words, words_found)
class GitTrie: def __init__(self, tree: GitObject, rev: str): self.tree = tree self.rev = rev self.trie = Trie() self.trie[()] = tree self._build(tree, ()) def _build(self, tree: GitObject, path: tuple): for obj in tree.scandir(): obj_path = path + (obj.name, ) self.trie[obj_path] = obj if obj.isdir: self._build(obj, obj_path) def open( self, key: tuple, mode: Optional[str] = "r", encoding: Optional[str] = None, ): obj = self.trie[key] if obj.isdir: raise IsADirectoryError return obj.open(mode=mode, encoding=encoding) def exists(self, key: tuple) -> bool: return bool(self.trie.has_node(key)) def isdir(self, key: tuple) -> bool: try: obj = self.trie[key] except KeyError: return False return obj.isdir def isfile(self, key: tuple) -> bool: try: obj = self.trie[key] except KeyError: return False return obj.isfile def walk(self, top: tuple, topdown: Optional[bool] = True): dirs = [] nondirs = [] def node_factory(_, path, children, obj): if path == top: assert obj.isdir list(filter(None, children)) elif obj.isdir: dirs.append(obj.name) else: nondirs.append(obj.name) self.trie.traverse(node_factory, prefix=top) if topdown: yield top, dirs, nondirs for dname in dirs: yield from self.walk(top + (dname, ), topdown=topdown) if not topdown: yield top, dirs, nondirs def stat(self, key: tuple) -> os.stat_result: obj = self.trie[key] return os.stat_result((obj.mode, 0, 0, 0, 0, 0, 0, 0, 0, 0))