from itertools import zip_longest, count, permutations
import re
def uniqc(xs):
seen = set((None,))
return [''.join('' if c in seen else seen.add(c) or c for c in w)
for w in xs]
def solve(q):
def term(var):
return '+'.join("a[{0}]*{1}".format(index[x], 10**i)
for i, x in enumerate(reversed(var)))
variables = re.findall(r'\w+', q)
steps = uniqc(zip_longest(*variables))
index = dict(zip(''.join(steps), count()))
limits = [sum(int(10**(e - 1)) for e in t)
for t in [[x - i for x in [len(v) for v in variables]]
for i in range(len(steps))]]
qq = re.sub('^([^=]+)=+(.*)$', r'(\1)-(\2)', q)
e = 'lambda a: abs(%s)' % re.sub(r'\w+', lambda m: term(m.group()), qq)
distance = eval(e)
distancex = lambda a: distance((a + (5,)*10)[:len(index)])
def advance(steps, limits, c, r):
if not steps:
if not distance(c):
yield re.sub(r'\w', lambda m: str(c[index[m.group()]]), q)
elif not steps[0]:
yield from advance(steps[1:], limits[1:], c, r)
else:
xs = r if c else set(range(1,10))
ps = (c + p for p in permutations(xs, len(steps[0])))
for d, p in sorted((distancex(p), p) for p in ps):
if d < limits[0]:
yield from advance(steps[1:], limits[1:], p, r - set(p))
yield from advance(steps, limits, (), set(range(10)))
testcase = '''
SEND + MORE = MONEY
APPLE + GRAPE = CHERRY
KYOTO + OSAKA = TOKYO
AOMORI + SAPPORO = FUKUOKA
KOCHI + OSAKA = NAGOYA
OKAYAMA + WAKAYAMA = KANAZAWA
FUKUOKA + NAGANO = YOKOHAMA
KAMAKURA + MORIOKA = NAGASAKI
KUMAMOTO + TOTTORI = WAKAYAMA
OKAYAMA + WAKAYAMA = YAMAGATA
TOTTORI + YAMAGATA = YOKOHAMA
'''
for case in testcase.strip().splitlines():
print(next(solve(case)))
ZnJvbSBpdGVydG9vbHMgaW1wb3J0IHppcF9sb25nZXN0LCBjb3VudCwgcGVybXV0YXRpb25zCmltcG9ydCByZQoKZGVmIHVuaXFjKHhzKToKICAgIHNlZW4gPSBzZXQoKE5vbmUsKSkKICAgIHJldHVybiBbJycuam9pbignJyBpZiBjIGluIHNlZW4gZWxzZSBzZWVuLmFkZChjKSBvciBjIGZvciBjIGluIHcpCiAgICAgICAgICAgIGZvciB3IGluIHhzXQoKZGVmIHNvbHZlKHEpOgogICAgZGVmIHRlcm0odmFyKToKICAgICAgICByZXR1cm4gJysnLmpvaW4oImFbezB9XSp7MX0iLmZvcm1hdChpbmRleFt4XSwgMTAqKmkpCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciBpLCB4IGluIGVudW1lcmF0ZShyZXZlcnNlZCh2YXIpKSkKCiAgICB2YXJpYWJsZXMgPSByZS5maW5kYWxsKHInXHcrJywgcSkKICAgIHN0ZXBzID0gdW5pcWMoemlwX2xvbmdlc3QoKnZhcmlhYmxlcykpCiAgICBpbmRleCA9IGRpY3QoemlwKCcnLmpvaW4oc3RlcHMpLCBjb3VudCgpKSkKICAgIGxpbWl0cyA9IFtzdW0oaW50KDEwKiooZSAtIDEpKSBmb3IgZSBpbiB0KQogICAgICAgICAgICAgIGZvciB0IGluIFtbeCAtIGkgZm9yIHggaW4gW2xlbih2KSBmb3IgdiBpbiB2YXJpYWJsZXNdXQogICAgICAgICAgICAgICAgICAgICAgICBmb3IgaSBpbiByYW5nZShsZW4oc3RlcHMpKV1dCiAgICBxcSA9IHJlLnN1YignXihbXj1dKyk9KyguKikkJywgcicoXDEpLShcMiknLCBxKQogICAgZSA9ICdsYW1iZGEgYTogYWJzKCVzKScgJSByZS5zdWIocidcdysnLCBsYW1iZGEgbTogdGVybShtLmdyb3VwKCkpLCBxcSkKICAgIGRpc3RhbmNlID0gZXZhbChlKQogICAgZGlzdGFuY2V4ID0gbGFtYmRhIGE6IGRpc3RhbmNlKChhICsgKDUsKSoxMClbOmxlbihpbmRleCldKQoKICAgIGRlZiBhZHZhbmNlKHN0ZXBzLCBsaW1pdHMsIGMsIHIpOgogICAgICAgIGlmIG5vdCBzdGVwczoKICAgICAgICAgICAgaWYgbm90IGRpc3RhbmNlKGMpOgogICAgICAgICAgICAgICAgeWllbGQgcmUuc3ViKHInXHcnLCBsYW1iZGEgbTogc3RyKGNbaW5kZXhbbS5ncm91cCgpXV0pLCBxKQogICAgICAgIGVsaWYgbm90IHN0ZXBzWzBdOgogICAgICAgICAgICB5aWVsZCBmcm9tIGFkdmFuY2Uoc3RlcHNbMTpdLCBsaW1pdHNbMTpdLCBjLCByKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHhzID0gciBpZiBjIGVsc2Ugc2V0KHJhbmdlKDEsMTApKQogICAgICAgICAgICBwcyA9IChjICsgcCBmb3IgcCBpbiBwZXJtdXRhdGlvbnMoeHMsIGxlbihzdGVwc1swXSkpKQogICAgICAgICAgICBmb3IgZCwgcCBpbiBzb3J0ZWQoKGRpc3RhbmNleChwKSwgcCkgZm9yIHAgaW4gcHMpOgogICAgICAgICAgICAgICAgaWYgZCA8IGxpbWl0c1swXToKICAgICAgICAgICAgICAgICAgICB5aWVsZCBmcm9tIGFkdmFuY2Uoc3RlcHNbMTpdLCBsaW1pdHNbMTpdLCBwLCByIC0gc2V0KHApKQoKICAgIHlpZWxkIGZyb20gYWR2YW5jZShzdGVwcywgbGltaXRzLCAoKSwgc2V0KHJhbmdlKDEwKSkpCgp0ZXN0Y2FzZSA9ICcnJwpTRU5EICsgTU9SRSA9IE1PTkVZCkFQUExFICsgR1JBUEUgPSBDSEVSUlkKS1lPVE8gKyBPU0FLQSA9IFRPS1lPCkFPTU9SSSArIFNBUFBPUk8gPSBGVUtVT0tBCktPQ0hJICsgT1NBS0EgPSBOQUdPWUEKT0tBWUFNQSArIFdBS0FZQU1BID0gS0FOQVpBV0EKRlVLVU9LQSArIE5BR0FOTyA9IFlPS09IQU1BCktBTUFLVVJBICsgTU9SSU9LQSA9IE5BR0FTQUtJCktVTUFNT1RPICsgVE9UVE9SSSA9IFdBS0FZQU1BCk9LQVlBTUEgKyBXQUtBWUFNQSA9IFlBTUFHQVRBClRPVFRPUkkgKyBZQU1BR0FUQSA9IFlPS09IQU1BCicnJwpmb3IgY2FzZSBpbiB0ZXN0Y2FzZS5zdHJpcCgpLnNwbGl0bGluZXMoKToKICAgIHByaW50KG5leHQoc29sdmUoY2FzZSkpKQo=