From 4cfb2cb0a3607f5a2e44a8bd461553c99c883583 Mon Sep 17 00:00:00 2001 From: Raphael Roberts Date: Sun, 26 May 2019 11:48:44 -0500 Subject: [PATCH] permutation cache --- candidate_cache.py | 51 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/candidate_cache.py b/candidate_cache.py index 670f2e9..2dc14a1 100644 --- a/candidate_cache.py +++ b/candidate_cache.py @@ -1,22 +1,38 @@ 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, frozenset(letters)) + return (dictionary_name, make_letter_key(letters)) -def candidates(letters, dictionary: Dictionary, min=2): - permutations = itertools.chain.from_iterable( - map(lambda r: itertools.permutations(letters, r), range(min, len(letters) + 1)) - ) - return dictionary.filter(map("".join, permutations)) +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), + ) + ), + ) + ) + return dictionary.filter(permutations), permutations 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): @@ -24,13 +40,34 @@ class CandidateCache: try: return self.cache[key] except KeyError: - data = candidates(letters, DICTS[dictionary_name]) + 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) 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