From c05ab89da60feb3ceb3983cdb07ab9d8a80aaeb5 Mon Sep 17 00:00:00 2001 From: vg Date: Tue, 19 May 2020 19:00:54 +0200 Subject: add cache system to avoid recalculating existing solutions --- .gitignore | 1 + solver.py | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 15c993e..d87335f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ __pycache__ *.pyc *.swp +*.cache diff --git a/solver.py b/solver.py index d10d347..8498f66 100755 --- a/solver.py +++ b/solver.py @@ -15,6 +15,8 @@ Options: ''' import copy +import os +import pickle import zlib import docopt @@ -42,6 +44,10 @@ class Kana: assert kana[0] in 'kstnhmryw' assert kana[1] in 'aiueo' + def dump(self): + 'return a list representing the members of this Kana' + return [self.type_name, self.kana] + def __repr__(self): return "%s(%s)" % (self.type_name, self.kana) @@ -250,10 +256,42 @@ class KanaGrid: grid.append(kana_void) else: grid.append(Kana(serialized_kana[0], serialized_kana[1])) - return KanaGrid(input_dict['size'], grid) + params = { + 'size': input_dict['size'], + 'grid': grid, + 'action_count': input_dict.get('action_count', 0), + 'score': input_dict.get('score', 0), + 'myst_count': input_dict.get('myst_count', 0), + } + return KanaGrid(**params) + + def load_reversed_parents(input_dict_list): + last_kanagrid = None + for input_dict in input_dict_list: + kanagrid = KanaGrid.load(input_dict) + kanagrid.parent = last_kanagrid + last_kanagrid = kanagrid + return last_kanagrid + + + def dump(self): + 'returns a dict representation of the kanagrid' + output_dict = { + 'size': [self.width, self.height], + 'action_count': self.action_count, + 'score': self.score, + 'myst_count': self.myst_count, + 'grid': [kana.dump() for kana in self.grid], + } + return output_dict - def dump(self, stream): - raise NotImplemented + def dump_reversed_parents(self): + kana_grids = [] + grid = self + while grid: + kana_grids.append(grid.dump()) + grid = grid.parent + return reversed(kana_grids) def __repr__(self): self.update_score() @@ -363,10 +401,17 @@ def search_all_solution(kanagrid, target_score, max_actions): yield grid +def get_solutions_from_cache(cache): + for solution in cache['solutions']: + kanagrid = KanaGrid.load_reversed_parents(solution) + yield kanagrid + + def main(): args = docopt.docopt(__doc__) - with open(args['YAML_GRID'], encoding='utf8') as stream: + grid_fn = args['YAML_GRID'] + with open(grid_fn, encoding='utf8') as stream: input_dict = yaml.safe_load(stream) kanagrid = KanaGrid.load(input_dict) target_score = input_dict['target_score'] @@ -380,13 +425,36 @@ def main(): if args['--print']: return - for grid in search_all_solution(kanagrid, target_score, max_actions): + mtime = os.path.getmtime + cache_file = '%s.cache' % grid_fn + + if os.path.exists(cache_file) and mtime(cache_file) >= mtime(grid_fn): + print('DEBUG: USING CACHED VERSION') + with open(cache_file, 'rb') as stream: + cached_version = pickle.load(stream) + generator = get_solutions_from_cache(cached_version) + cache_generation = None + else: + generator = search_all_solution(kanagrid, target_score, max_actions) + cache_generation = { + 'max_actions': 1, + 'target_score': 1, + 'solutions': [], + } + + for grid in generator: + if cache_generation: + cache_generation['solutions'].append(grid.dump_reversed_parents()) print("="*80) if args['-p']: print(repr_grid_with_parents(grid)) else: print(grid) + if cache_generation: + with open(cache_file, 'wb') as stream: + pickle.dump(cache_generation, stream) + if __name__ == '__main__': main() -- cgit v1.2.3