乘法解迷求解


      I C J        
    x  H C
   -------
   B E I C        
 J J A G
 ---------      
 I A B A C

 

乘法解迷游戏,表达式中的每个字母代表了一个数字,不同字母代表的不同的数字,

游戏来自于emacs编辑器菜单tools/games/Multiplication Puzzle,

如上式的解迷结果为:


     8 5 7
    x  9 5
   -------
   4 2 8 5
7 7 1 3
 ---------   
 8 1 4 1 5

 

花了一下午时间,用python写了两个方法,一种是用全枚举,一个是只枚举乘数,两者运行效率相差好几千倍! 算法太重要了!

 

import string,sys
#aaa = raw_input("  AAA * BB = CCCC + DDDD = EEEE ? ").rstrip().lstrip()
#aaa = aaa.split(" ")
aaa=sys.argv[1:]
bbb = aaa[1]
ccc = aaa[2]
ddd = aaa[3]
eee = aaa[4]
aaa = aaa[0]
vs = []
vss=[]
vm = ['0','1','2','3','4','5','6','7','8','9']
symv = {}

for t in aaa:
    if t not in vs:
        vs.append(t)
        vss.append(t)
for t in bbb:
    if t not in vs:
        vs.append(t)
        vss.append(t)
for t in ccc:
    if t not in vs: vs.append(t)
for t in ddd:
    if t not in vs: vs.append(t)
for t in eee:
    if t not in vs: vs.append(t)

def checkv():
    aaav=string.atoi(symv[aaa[0]]+symv[aaa[1]]+symv[aaa[2]])
    b0=string.atoi(symv[bbb[0]])
    b1=string.atoi(symv[bbb[1]])
    bbbv=string.atoi(symv[bbb[0]]+symv[bbb[1]])
    cccv=string.atoi(symv[ccc[0]]+symv[ccc[1]]+symv[ccc[2]]+symv[ccc[3]])
    dddv=string.atoi(symv[ddd[0]]+symv[ddd[1]]+symv[ddd[2]]+symv[ddd[3]])
    eeev=string.atoi(symv[eee[0]]+symv[eee[1]]+symv[eee[2]]+symv[eee[3]]+symv[eee[4]])
    chv = (aaav*bbbv==eeev) and (aaav*b0==dddv) and (aaav*b1==cccv)
    #if(aaav==915 and bbbv==86 and cccv==5490 and dddv==7320): print "try", eeev
    if(chv):print "great!!:", aaav, bbbv
    return chv

def checkv1():
    aaav=string.atoi(symv[aaa[0]]+symv[aaa[1]]+symv[aaa[2]])
    b0=string.atoi(symv[bbb[0]])
    b1=string.atoi(symv[bbb[1]])
    bbbv=string.atoi(symv[bbb[0]]+symv[bbb[1]])
    tcccv=aaav*b1
    tdddv=aaav*b0
    teeev=aaav*bbbv
    t=1000
    for i in xrange(0, 4):
        if ccc[i] not in symv: symv[ccc[i]]=vm[tcccv/t]
        else:
            if symv[ccc[i]]!=vm[tcccv/t]: return 0
        tcccv%=t
        t/=10
    t=1000
    for i in xrange(0, 4):
        if ddd[i] not in symv: symv[ddd[i]]=vm[tdddv/t]
        else:
            if symv[ddd[i]]!=vm[tdddv/t]: return 0
        tdddv%=t
        t/=10
    t=10000
    for i in xrange(0, 5):
        if eee[i] not in symv: symv[eee[i]]=vm[teeev/t]
        else:
            if symv[eee[i]]!=vm[teeev/t]: return 0
        teeev%=t
        t/=10

    print "great!!:", aaav, bbbv
    return 1

def fullarrange(lvm, lvs, vs, checkvt):
    total=1
    for i in xrange(lvm-lvs+1, lvm+1):
        total*=i
    for i in xrange(0,total):
        k=lvm
        vmtmp=vm[:]
        symv.clear()
        for j in xrange(0, lvs):
            t=(i%k)+j
            symv[vs[j]]=vmtmp[t]
            #vmtmp.pop(i%k)
            vmtmp[t]=vmtmp[j]
            i/=k
            k-=1
        if(checkvt()):
            break


def resolv0():
    fullarrange(len(vm), len(vs), vs, checkv)

def resolv1():
    fullarrange(len(vm), len(vss), vss, checkv1)

resolv1()

 

你可能感兴趣的:(乘法解迷求解)