def create_pref_to_topk_dict(fdir, f_compressed, fname, k): i2r, i2c, smat = parallel_get_qp2q_sparse_data(fdir=fdir, compressed=f_compressed, n_jobs=16) sdf = SparseDataFrame(data_matrix=smat, columns=i2c, rows=i2r) LOGGER.info("Created sparsedataframe") flat_mat = np.sum(sdf.data_matrix, axis=0) # Compute sum for each col LOGGER.info("Computed sum of each col") assert flat_mat.shape == (1, sdf.data_matrix.shape[1]) LOGGER.info("Creating label_freq dictionary") label_freq = {c: int(flat_mat[0, sdf.c2i[c]]) for c in sdf.c2i} LOGGER.info("Created label_freq dictionary") all_prefs = {label[:i]: [] for label in label_freq for i in range(len(label) + 1)} LOGGER.info("Number of prefixes = {}".format(len(all_prefs))) label_trie = CharTrie() label_trie.update(label_freq) LOGGER.info("Created label trie") all_prefs_to_topk = { pref: get_top_k_w_label_trie(prefix=pref, label_trie=label_trie, k=k) for pref in tqdm(all_prefs) } res_dir = os.path.dirname(fname) Path(res_dir).mkdir(exist_ok=True, parents=True) with open(fname, "w") as f: json.dump(all_prefs_to_topk, f) LOGGER.info("Saved top-k dict in {}".format(fname))
def create_query_freq_based_trie(fdir, f_compressed, fname): i2r, i2c, smat = parallel_get_qp2q_sparse_data(fdir=fdir, compressed=f_compressed, n_jobs=16) sdf = SparseDataFrame(data_matrix=smat, columns=i2c, rows=i2r) LOGGER.info("Created sparsedataframe") trie = CharTrie() LOGGER.info("Computed sum of each col") flat_mat = np.sum(sdf.data_matrix, axis=0) # Compute sum for each col assert flat_mat.shape == (1, sdf.data_matrix.shape[1]) LOGGER.info("Creating label_freq dictionary") label_freq = {c: flat_mat[0, sdf.c2i[c]] for c in sdf.c2i} LOGGER.info("Created label_freq dictionary") trie.update(label_freq) LOGGER.info("Created trie") res_dir = os.path.dirname(fname) Path(res_dir).mkdir(exist_ok=True, parents=True) with open("{}".format(fname), "wb") as trie_file: pickle.dump(trie, trie_file, protocol=pickle.HIGHEST_PROTOCOL) LOGGER.info("Saved trie in {}/{}".format(res_dir, fname))
class Solver: def __init__(self, cells, dictionary=None): self.cells = [ Cell( c['letter'], c.get('points', 1), c.get('P', 1), c.get('S', 1), ) for c in cells ] self.letters = [c['letter'] for c in cells] self.candidates = {} # word => (positions, value) self.dictionary = dictionary if not dictionary: self.dictionary = CharTrie() print('Loading custom words ... ', end="") with open('SK-custom.txt') as f: self.dictionary.update( (w, True) for w in f.read().splitlines()) print(len(self.dictionary)) def word_value(self, visited): val = 0 S = 1 for pos in visited: cell = self.cells[pos] val += cell.points * cell.P S *= cell.S return val * S def next_char(self, visited, pos): visited = visited + (pos, ) word = ''.join((self.letters[p] for p in visited)) has = self.dictionary.has_node(word) if has & CharTrie.HAS_VALUE: newval = self.word_value(visited) if self.candidates.get(word, (None, 0))[1] < newval: self.candidates[word] = (visited, newval) # print(word) # Don't continue if thera are no words with this prefix if not has & CharTrie.HAS_SUBTRIE: return row = pos // 4 col = pos % 4 prev_row = row - 1 next_row = row + 1 prev_col = col - 1 next_col = col + 1 if next_row < 4: # Adds the charcter S the current pos pos = next_row * 4 + col if pos not in visited: self.next_char(visited, pos) #Adds the character SE the current pos pos = next_row * 4 + next_col if next_col < 4 and pos not in visited: self.next_char(visited, pos) if next_col < 4: # Adds the charcter E of the current pos pos = row * 4 + next_col if pos not in visited: self.next_char(visited, pos) #Adds the character NE the current pos pos = prev_row * 4 + next_col if prev_row >= 0 and pos not in visited: self.next_char(visited, pos) if prev_row >= 0: # Adds the charcter N the current pos pos = prev_row * 4 + col if pos not in visited: self.next_char(visited, pos) # Adds the charcter NW of the current pos pos = prev_row * 4 + prev_col if prev_col >= 0 and pos not in visited: self.next_char(visited, pos) if prev_col >= 0: # Adds the charcter W of the current pos pos = row * 4 + prev_col if pos not in visited: self.next_char(visited, pos) # Adds the charcter SW of the current pos pos = next_row * 4 + prev_col if next_row < 4 and pos not in visited: self.next_char(visited, pos) def solve_and_swipe(self): for pos in range(0, 16): self.next_char((), pos) # sort by length pyautogui.moveTo(x0, y0, duration=0.1) pyautogui.click(duration=0.1) for word, visited_val in self.candidates.items(): print(word, visited_val[1]) self.swipe(visited_val[0]) def swipe(self, positions): grid = 94 pos = positions[0] pyautogui.moveTo(x0 + (pos % 4) * grid, y0 + (pos // 4) * grid, duration=0.1) pyautogui.mouseDown(button='left', logScreenshot=False, _pause=False, duration=0.1) for pos in positions[1:]: pyautogui.moveTo(x0 + (pos % 4) * grid, y0 + (pos // 4) * grid, duration=0.1) pyautogui.mouseUp(button='left', logScreenshot=False, _pause=False, duration=0.1)