从五个数字中得出一个数字X,每个数字都有两个数字

时间:2016-11-21 12:02:32

标签: python

我编写下面的代码,根据0到9999范围内的5个数字的输入得出数字X.这5个数字每个都有两个数字,X也有,但它们的位置是错误的(例如一个数字)在千位中给出了数千位的X)。

示例输入:

6087,5173,1358,3825,2531

对于此输入,预期输出为:

8712

下面的代码计算X,但它是强力的。如何减少时间复杂度?

m = ('6087','5173','1358','3825','2531')
x = ['']*5

for i in range(0,5):
    a=int(m[i])/1000
    b=int(m[i])/100-10*a
    c=int(m[i])/10-100*a-10*b
    d=int(m[i])%10
    x[i]=[a,b,c,d]

for num in range(0,10000):
    thousand=num/1000
    hundred=num/100-10*thousand
    decade=num/10-100*thousand-10*hundred
    digits=num%10
    count=0
    for j in range(0,5):
        if (thousand==x[j][1] or thousand==x[j][2] or thousand==x[j][3]) and (hundred==x[j][0] or hundred==x[j][2] or hundred==x[j][3]) and (decade!=x[j][0] and decade!=x[j][1] and decade!=x[j][2] and decade!=x[j][3]) and (digits!=x[j][0] and digits!=x[j][1] and decade!=x[j][2] and decade!=x[j][3]):
            count+=1
        elif (thousand==x[j][1] or thousand==x[j][2] or thousand==x[j][3]) and (decade==x[j][0] or decade==x[j][1] or decade==x[j][3]) and (hundred!=x[j][0] and hundred!=x[j][1] and hundred!=x[j][2] and hundred!=x[j][3]) and (digits!=x[j][0] and digits!=x[j][1] and decade!=x[j][2] and decade!=x[j][3]):
            count+=1
        elif (thousand==x[j][1] or thousand==x[j][2] or thousand==x[j][3]) and (digits==x[j][0] or digits==x[j][1] or digits==x[j][2]) and (hundred!=x[j][0] and hundred!=x[j][1] and hundred!=x[j][2] and hundred!=x[j][3]) and  (decade!=x[j][0] and decade!=x[j][1] and decade!=x[j][2] and decade!=x[j][3]):
            count+=1
        elif (hundred==x[j][0] or hundred==x[j][2] or hundred==x[j][3]) and (decade==x[j][0] or decade==x[j][1] or decade==x[j][3]) and (thousand!=x[j][0] and thousand!=x[j][1] and thousand!=x[j][2] and thousand!=x[j][3]) and  (digits!=x[j][0] and digits!=x[j][1] and decade!=x[j][2] and decade!=x[j][3]):
            count+=1
        elif (hundred==x[j][0] or hundred==x[j][2] or hundred==x[j][3]) and (digits==x[j][0] or digits==x[j][1] or digits==x[j][2]) and (thousand!=x[j][0] and thousand!=x[j][1] and thousand!=x[j][2] and thousand!=x[j][3]) and  (decade!=x[j][0] and decade!=x[j][1] and decade!=x[j][2] and decade!=x[j][3]):
            count+=1
        elif (decade==x[j][0] or decade==x[j][1] or decade==x[j][3]) and (digits==x[j][0] or digits==x[j][1] or digits==x[j][2]) and (thousand!=x[j][0] and thousand!=x[j][1] and thousand!=x[j][2] and thousand!=x[j][3]) and  (hundred!=x[j][0] and hundred!=x[j][1] and hundred!=x[j][2] and hundred!=x[j][3]):
            count+=1
    if count == 5:
        print num

1 个答案:

答案 0 :(得分:0)

您可以使用它作为替代方法,执行递归搜索,并消除可能性,因为它选择的数字对可能是正确的(但错位)。如果它发现通过处理更多输入找不到解决方案,它会回溯并尝试下一对数字,等等。

一旦输入被处理到最深层次的递归,就会知道4个数字,并且另一个递归搜索会将这4个数字分配给仍然可能的位置。如果成功,函数会立即退出递归,返回找到的值。

def findMatch(guesses):
    def assign(pos, digits, result):
        if len(digits) == 0: return True
        digit = digits[0]
        for j in pos[digit]:
            if result[j] == None:
                result[j] = digit
                if assign(pos, digits[1:], result):
                    return ''.join(map(str, result))
                result[j] = None
        return False

    def recurse(guesses, pos, must):
        if len(must) > 4: return False
        if len(guesses) == 0:
            if len(must) < 4: return False # all digits in solution must be unique
            return assign(pos, list(must), [None, None, None, None])
        digits = list(map(int, guesses[0]))
        permutations = ((0,1),(2,3),(0,2),(1,3),(0,3),(1,2))
        for i, (j, k) in enumerate(permutations):
            (l, m) = permutations[i ^ 1]
            [dig1, dig2, dig3, dig4] = [digits[j], digits[k], digits[l], digits[m]]
            if (len(pos[dig1]) > int(j in pos[dig1]) and 
                    len(pos[dig2]) > int(k in pos[dig2]) and
                    dig3 not in must and dig4 not in must):
                saved = [pos[dig1], pos[dig2], pos[dig3], pos[dig4]]
                # remove possibilities
                [pos[dig1], pos[dig2], pos[dig3], pos[dig4]] = [
                    pos[dig1] - set([j]), pos[dig2] - set([k]), set(), set()]
                found = recurse(guesses[1:], pos, must | set((dig1,dig2)))
                if found:
                    return found
                # backtrack
                [pos[dig1], pos[dig2], pos[dig3], pos[dig4]] = saved
        return False

    return recurse(guesses, [set([0,1,2,3]) for i in range(0,10)], set())

guesses = ['6087','5173','1358','3825','2531']
print (findMatch(guesses))

这将比您实施的强力方法更快地找到解决方案。此代码假定解决方案必须由不同的数字组成 - 因此没有一个数字出现两次。