|
|
|
@ -1,38 +1,31 @@ |
|
|
|
import itertools |
|
|
|
from collections import Counter |
|
|
|
from dictionary import Dictionary, DICTS |
|
|
|
|
|
|
|
|
|
|
|
def make_letter_key(letters): |
|
|
|
return frozenset(Counter(letters).items()) |
|
|
|
|
|
|
|
|
|
|
|
def make_key(dictionary_name, letters): |
|
|
|
return (dictionary_name, make_letter_key(letters)) |
|
|
|
return (dictionary_name, frozenset(Counter(letters).items())) |
|
|
|
|
|
|
|
|
|
|
|
def candidates(letters, dictionary: Dictionary, min=2, permutations=None): |
|
|
|
if permutations is None: |
|
|
|
permutations = tuple( |
|
|
|
map( |
|
|
|
"".join, |
|
|
|
itertools.chain.from_iterable( |
|
|
|
map( |
|
|
|
lambda r: itertools.permutations(letters, r), |
|
|
|
range(min, len(letters) + 1), |
|
|
|
) |
|
|
|
), |
|
|
|
letter_counter = Counter(letters) |
|
|
|
possibilities = [] |
|
|
|
for word in dictionary.word_frequency.keys(): |
|
|
|
word_counter = Counter(word) |
|
|
|
try: |
|
|
|
add = all( |
|
|
|
word_counter[key] <= letter_counter[key] for key in word_counter.keys() |
|
|
|
) |
|
|
|
) |
|
|
|
return dictionary.filter(permutations), permutations |
|
|
|
except KeyError: |
|
|
|
add = False |
|
|
|
if add: |
|
|
|
possibilities.append(word) |
|
|
|
return possibilities |
|
|
|
|
|
|
|
|
|
|
|
class CandidateCache: |
|
|
|
def __init__(self, maxsize=5): |
|
|
|
self.maxsize = maxsize |
|
|
|
self.cache = {} |
|
|
|
self.permutations_cache = {} |
|
|
|
self.permutations_keys = [] |
|
|
|
self.keys = [] |
|
|
|
|
|
|
|
def get(self, dictionary_name, letters): |
|
|
|
@ -40,34 +33,15 @@ class CandidateCache: |
|
|
|
try: |
|
|
|
return self.cache[key] |
|
|
|
except KeyError: |
|
|
|
try: |
|
|
|
permutations = self.get_permutation(letters) |
|
|
|
add = False |
|
|
|
except KeyError: |
|
|
|
permutations = None |
|
|
|
add = True |
|
|
|
data, permutations = candidates( |
|
|
|
letters, DICTS[dictionary_name], permutations=permutations |
|
|
|
) |
|
|
|
if add: |
|
|
|
self.append_permutation(letters, permutations) |
|
|
|
|
|
|
|
data = candidates(letters, DICTS[dictionary_name]) |
|
|
|
|
|
|
|
self.create(key, data) |
|
|
|
return data |
|
|
|
|
|
|
|
def get_permutation(self, letters): |
|
|
|
key = make_letter_key(letters) |
|
|
|
return self.permutations_cache[key] |
|
|
|
|
|
|
|
def create(self, key, data): |
|
|
|
if len(self.keys) > self.maxsize: |
|
|
|
key = self.keys.pop() |
|
|
|
del self.cache[key] |
|
|
|
self.keys.insert(0, key) |
|
|
|
self.cache[key] = data |
|
|
|
|
|
|
|
def append_permutation(self, letters, permutations): |
|
|
|
if len(self.permutations_keys) > self.maxsize: |
|
|
|
dkey = self.permutations_keys.pop() |
|
|
|
del self.permutations_cache[dkey] |
|
|
|
key = make_letter_key(letters) |
|
|
|
self.permutations_cache[key] = permutation |