You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

73 lines
2.2 KiB

  1. import itertools
  2. from collections import Counter
  3. from dictionary import Dictionary, DICTS
  4. def make_letter_key(letters):
  5. return frozenset(Counter(letters).items())
  6. def make_key(dictionary_name, letters):
  7. return (dictionary_name, make_letter_key(letters))
  8. def candidates(letters, dictionary: Dictionary, min=2, permutations=None):
  9. if permutations is None:
  10. permutations = tuple(
  11. map(
  12. "".join,
  13. itertools.chain.from_iterable(
  14. map(
  15. lambda r: itertools.permutations(letters, r),
  16. range(min, len(letters) + 1),
  17. )
  18. ),
  19. )
  20. )
  21. return dictionary.filter(permutations), permutations
  22. class CandidateCache:
  23. def __init__(self, maxsize=5):
  24. self.maxsize = maxsize
  25. self.cache = {}
  26. self.permutations_cache = {}
  27. self.permutations_keys = []
  28. self.keys = []
  29. def get(self, dictionary_name, letters):
  30. key = make_key(dictionary_name, letters)
  31. try:
  32. return self.cache[key]
  33. except KeyError:
  34. try:
  35. permutations = self.get_permutation(letters)
  36. add = False
  37. except KeyError:
  38. permutations = None
  39. add = True
  40. data, permutations = candidates(
  41. letters, DICTS[dictionary_name], permutations=permutations
  42. )
  43. if add:
  44. self.append_permutation(letters, permutations)
  45. self.create(key, data)
  46. return data
  47. def get_permutation(self, letters):
  48. key = make_letter_key(letters)
  49. return self.permutations_cache[key]
  50. def create(self, key, data):
  51. if len(self.keys) > self.maxsize:
  52. key = self.keys.pop()
  53. del self.cache[key]
  54. self.keys.insert(0, key)
  55. self.cache[key] = data
  56. def append_permutation(self, letters, permutations):
  57. if len(self.permutations_keys) > self.maxsize:
  58. dkey = self.permutations_keys.pop()
  59. del self.permutations_cache[dkey]
  60. key = make_letter_key(letters)
  61. self.permutations_cache[key] = permutation