diff options
| -rwxr-xr-x | solver.py | 56 | 
1 files changed, 44 insertions, 12 deletions
@@ -17,6 +17,7 @@ Options:  import copy  import os  import pickle +import time  import zlib  import docopt @@ -28,6 +29,8 @@ class Kana:               'ar_u', 'ar_r', 'ar_d', 'ar_l')      slime_merge_types = ('norm', 'froz', 'ar_u', 'ar_r', 'ar_d', 'ar_l') +    cache = {} +      def __init__(self, type_name, kana=None):          self.type_name = type_name          self.kana = kana @@ -44,6 +47,13 @@ class Kana:                  assert kana[0] in 'kstnhmryw'                  assert kana[1] in 'aiueo' +    def create(type_name, kana=None): +        key = (type_name, kana) +        if key in Kana.cache: +            return Kana.cache[key] +        new_kana = Kana.cache[key] = Kana(type_name, kana) +        return new_kana +      def dump(self):          'return a list representing the members of this Kana'          return [self.type_name, self.kana] @@ -54,7 +64,8 @@ class Kana:      def __eq__(self, other):          return self.type_name == other.type_name and self.kana == other.kana -kana_void = Kana('void') + +kana_void = Kana.create('void')  class KanaGrid: @@ -95,6 +106,12 @@ class KanaGrid:          }          if kana1.type_name in table_ok:              if kana2.type_name in table_ok[kana1.type_name]: + +                # early return for empty norm to empty norm +                if kana1.type_name == kana2.type_name == 'norm' \ +                        and kana1.kana is kana2.kana is None: +                    return False +                  ar_vect_ok = {                          'ar_u': ( 0, -1),                          'ar_l': (-1,  0), @@ -117,7 +134,7 @@ class KanaGrid:              if kana.type_name == 'myst':                  new_grid = self.copy()                  new_grid.action_count += 1 -                new_grid.set_kana(pos, Kana('norm', kana.kana)) +                new_grid.set_kana(pos, Kana.create('norm', kana.kana))                  return new_grid          elif action_type in ('up', 'right', 'down', 'left'):              pos_map = { @@ -130,10 +147,13 @@ class KanaGrid:              if kana.type_name == 'slim':                  kana2 = self.get_kana(pos_dest)                  if kana2.type_name in Kana.slime_merge_types and kana2.kana: +                    # early return for slime merging for same vowel +                    if kana2.kana[1] == kana.kana[0]: +                        return                      new_grid = self.copy()                      new_grid.action_count += 1 -                    new_kana1 = Kana('void') -                    new_kana2 = Kana( +                    new_kana1 = kana_void +                    new_kana2 = Kana.create(                              kana2.type_name,                              kana2.kana[0] + kana.kana[0],                      ) @@ -196,7 +216,10 @@ class KanaGrid:          #, highest_length_chain # easy to add if needed      def update_score(self): -        self.score, self.myst_count = self.longest_chain() +        if not self.score: +            # if self.score == 0 calculate the score as the score is always at +            # the bare minimum equal to 1. +            self.score, self.myst_count = self.longest_chain()      def get_hash(self):          data = ''.join(( @@ -221,6 +244,7 @@ class KanaGrid:          elif pos[1] < 0 or pos[1] >= self.height:              return          self.grid[pos[0]+pos[1]*self.width] = kana +        self.score = 0      def swap_kana(self, pos1, pos2):          kana_dst = self.get_kana(pos2) @@ -250,12 +274,10 @@ class KanaGrid:              kana_dst = self.get_kana(pos_dst)      def load(input_dict): -        grid = [] -        for serialized_kana in input_dict['grid']: -            if serialized_kana[0] == 'void': -                grid.append(kana_void) -            else: -                grid.append(Kana(serialized_kana[0], serialized_kana[1])) +        grid = [ +            Kana.create(serialized_kana[0], serialized_kana[1]) +            for serialized_kana in input_dict['grid'] +        ]          params = {              'size': input_dict['size'],              'grid': grid, @@ -425,11 +447,12 @@ def main():      if args['--print']:          return +    solver_start_time = int(time.time())      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') +        print(f'Using cached version from {cache_file}')          with open(cache_file, 'rb') as stream:              cached_version = pickle.load(stream)          generator = get_solutions_from_cache(cached_version) @@ -455,6 +478,15 @@ def main():          with open(cache_file, 'wb') as stream:              pickle.dump(cache_generation, stream) +    solver_stop_time = int(time.time()) +    solver_delta_time = solver_stop_time - solver_start_time +    hours = solver_delta_time // 3600 +    minutes = (solver_delta_time // 60) % 60 +    seconds = solver_delta_time % 60 + +    print(f'time taken to calculate: {hours:02d}:{minutes:02d}:{seconds:02d}') + +  if __name__ == '__main__':      main()  | 
