def recurse_generate(words: list, trie: Trie, square_size: int, chosen_words_length=0) -> list: if chosen_words_length >= square_size or square_size <= 1: if check_solution_is_valid(words, square_size): return words return None # build up the solution letter by letter # on each iteration we check if the substring is a key inside the Trie # if not a key then we know the current permutation is not a solution so return None # loop through the characters for i in range(chosen_words_length, square_size): prefix = "".join(word[i] for word in words) # using the soon to be deprecated function because it runs ~30% faster if not trie.has_keys_with_prefix(prefix): return None prefix = "".join(word[chosen_words_length] for word in words) # we use a prefix to dictate which key to start going over for word in trie.iterkeys(prefix): new_list = words + [word] res = recurse_generate(new_list, trie, square_size, chosen_words_length + 1) if res: return res return None