def pattern(st): d={} rv=[] for l in st: if not(l in d): d[l]=len(d) rv.append(d[l]) return tuple(rv)
for i in pattern_index.get(pattern(u''),set()): print words_list[i],
for i in letters_order_index.get((1,u''),set()): print words_list[i],
for i in letters_existance_index.get((1,u''), set()): print words_list[i],
import re, itertools import codecs from collections import defaultdict from copy import copy def pattern(st): d={} rv=[] for l in st: if not(l in d): d[l]=len(d) rv.append(d[l]) return tuple(rv) def substitutions_generator(st): words = re.split('[-*+]',st) letters = list(set(''.join(words))) first_letters = set([w[0] for w in words]) for comb in itertools.combinations(range(10),len(letters)): d = dict(zip(letters,comb)) if not any(d[k] == 0 for k in first_letters): yield d def eval_substitution(st,substitution): reverse_substitution = {} for k in substitution: reverse_substitution[str(substitution[k])] = k st = st.replace(k,str(substitution[k])) result = str(eval(st)) tojd = st + "=" + result forbidden = set([]) #, substitution for k in reverse_substitution: if not(k in result): forbidden.add(reverse_substitution[k]) else: result = result.replace(k,reverse_substitution[k]) return result,tojd,forbidden def gen_indexes(path, limit = None): freq_dict = {} pattern_index = defaultdict(set) letters_order_index = defaultdict(set) words_list=[] letters_existance_index = defaultdict(set) for i,l in enumerate(codecs.open(path,"r","utf-8-sig")): if limit and i>limit:break w,n=l.split() words_list.append(w) index = len(words_list)-1 freq_dict[index]=int(n) pattern_index[pattern(w)].add(index) for k in list(enumerate(w)): letters_order_index[k].add(index) for l in w: letters_existance_index[l].add(index) return words_list, pattern_index, letters_order_index, letters_existance_index, freq_dict def generate_cryptarithm(st, indexes): words_list, pattern_index, letters_order_index, letters_existance_index, freq_dict = indexes d=defaultdict(list) for sub in substitutions_generator(st): res,tojd,forbidden = eval_substitution(st,sub) cur_indexes=copy(pattern_index.get(pattern(res),set([]))) if not cur_indexes: continue for lk in list(enumerate(res)): if not(lk[1] in '0123456789'): cur_indexes&=letters_order_index.get(lk,set([])) for l in forbidden: cur_indexes-=letters_existance_index[l] if cur_indexes: for w in cur_indexes: d[w].append((sub,tojd)) for k in sorted(d.keys(), key = lambda x:freq_dict[x], reverse = True): if len(d[k]) ==1: tojd=d[k][0][1] print "%s=%s,%s"%(st,words_list[k],tojd)
# -*- coding: utf-8 -*- from cryptarithm import generate_cryptarithm,gen_indexes indexes = gen_indexes("wiki_freq.txt", 400000) l1=[u'',u'',u'',u''] l2=[u'',u'',u'',u'', u''] for w1 in l1: for w2 in l2: generate_cryptarithm(w1+u'+'+w2,indexes) generate_cryptarithm(w1+u'*'+w2,indexes) generate_cryptarithm(w1+u'-'+w2,indexes)
Source: https://habr.com/ru/post/189050/
All Articles