c

codeye

V1

2022/10/13阅读:19主题:默认主题

3 digit code

原题如下图示

密码锁是3位的密码,猜5种组合分别有下面的提示

7 9 3 :只有1个对的,而且在正确位置;

7 2 5 :只有1个对的,但位置不对;

3 1 7 :有两个数是对的,但都不在正确位置;

8 4 9 : 没有包含正确的数字

8 9 1 : 只有1个对的,但位置不对;

逻辑任务尝试编程解决。好处是有的,例如修改题面的数字,也能迅速获取密码答案。

初始化arrs二维数组表达所有的输入信息!简单将5个声明解析为数组中的第4位和第5位数值,具体如下:

arrs = [
        [7,9,3,1,1], # n=1,p=1, 包含1个密码数字,且位置对
        [7,2,5,1,0], # n=1,p=0, 包含1个密码数字,但位置不对
        [3,1,7,2,0], # n=2,p=0, 包含2个密码数字,但位置都不对
        [8,4,9,0,0], # n=0,p=0, 没有包含
        [8,9,1,1,0]  # n=1,p=0, 包含1个密码数字,但位置不对
        ]

第一步:筛选0-9之间可能出现在密码里的数字

def filter(arrs):
    dt,rem = set(),set()
    for arr in arrs:
        if arr[3] > 0:
            dt.update(arr[:3])
        if arr[3] == 0:
            rem = set(arr[:3])
            # not good for: dt - set(arr[:3])
    return dt - rem

第二步:在组合中筛选符合任务中 5 个声明的

变量n是包含密码数字的个数,p是位置正确的个数;

只有满足全部5个#声明的组合返回结果 True,否则返回False


def judge(num,arrs):
    # filter(arrs) < digit = list(range(10))
    #变量n是包含密码数字的个数, p是位置正确的个数;
    #只有满足全部5个声明的组合返回结果 True,否则False
    for arr in arrs:
        n,p = arr[3],arr[4]
        temp = list(zip(num,arr[:3]))
        bool_pos = sum([x==y for x,y in temp])
        common = set(arr[:3]) & set(num)
        if bool_pos != p or len(common) != n:
           return False
    else:return True

第三步:排列组合并逐一判断


from itertools import permutations
def main(arrs,lngth=3):
    ans = []
    s = filter(arrs)
    seq = list(permutations(s,lngth))
    return [num for num in seq if judge(num,arrs)]
    
print('main:',main(arrs,3))
main: [(1, 5, 3)]

扩展任务

你可以修改初始化二维数组,例如:arrs第5行的[8,9,1],改为[8,9,5],你猜猜结果如何?

arrs = [
        [7,9,3,1,1], # n=1,p=1, 包含1个密码数字,且位置对
        [7,2,5,1,0], # n=1,p=0, 包含1个密码数字,但位置不对
        [3,1,7,2,0], # n=2,p=0, 包含2个密码数字,但位置都不对
        [8,4,9,0,0], # n=0,p=0, 没有包含
        [8,9,5,1,0]  # n=1,p=0, 包含1个密码数字,但位置不对
        ]

运行以上程序,发现结果不变!正确密码还是(1, 5, 3) 推理看是否正确?

扩展之二

保持二维数组元素的前3个元素不变,修改声明,例如第3行[3,1,7,2,0],修改位[3,1,7,1,0],返回结果是空,没有满足的组合;

但如果继续修改第4行,[8,4,9,0,0]改为[8,4,9,1,0],再看看有什么变化? 具体如下初始化arrs

arrs = [
        [7,9,3,1,1], # n=1,p=1, 包含1个密码数字,且位置对
        [7,2,5,1,0], # n=1,p=0, 包含1个密码数字,但位置不对
        [3,1,7,1,0], # n=1,p=0, 包含1个密码数字,但位置都不对
        [8,4,9,1,0], # n=0,p=0, 包含1个密码数字,但位置都不对
        [8,9,1,1,0]  # n=1,p=0, 包含1个密码数字,但位置不对
        ]

返回两个结果:(2, 8, 3), (5, 8, 3)

上述可以继续优化,优化的方向是声明变化时,修改初始化arrs,判断是否输出为空。

分类:

后端

标签:

后端

作者介绍

c
codeye
V1