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
def test(): # 1. build a trie d = dict(zero=0, one=1, two=2, three=3, four=4, five=5, six=6, seven=7, eight=8, nine=9, ten=10, eleven=11, twelve=12, thirteen=13, fourteen=10, fifteen=15, sixteen=16, seventeen=17, eighteen=18, nineteen=19, twenty=20, thirty=30, fourty=40, fifty=50, sixty=60, seventy=70, eighty=80, ninety=90, hundred=100) t = Trie(list(d.keys())) # 2. scan 2000 "sentences" with it for _ in range(1000): # scanning for the longest matches only in sentence 1 i = S1[0] #print(TEXT[i:S1[1]]) while i < S1[1]: pfx = list(t.prefixes(TEXT[i:S1[1]])) if pfx: k = pfx[-1] #print(d[k]) i += len(k) else: i += 1 # scanning for all matches in sentence 2 i = S2[0] #print(TEXT[i:S2[1]]) s = 0 while i < S2[1]: for k in t.prefixes(TEXT[i:S2[1]]): #print(k) s += d[k] i += 1 if s != 142: raise RuntimeError(str(s)) # 3. make a real list of all keys in the trie if 'nine' not in list(t.iterkeys()): raise RuntimeError(str(list(t.iterkeys())))
class TrieNameDB(NameDB): def __init__(self, pair_gen): self._dic = self._construct_dic(pair_gen) self._index = Trie(self._dic.keys()) def _construct_dic(self, pair_gen): dic = collections.defaultdict(list) for k, v in pair_gen: dic[k.lower()].append((k, v)) return dic def find_by_prefix(self, str, limit=50): result = [] for key in self._index.iterkeys(str.lower()): result.extend(self._dic[key]) if limit <= len(result): break return result[:limit]