美文网首页
利用Python求解 小明的手机密码

利用Python求解 小明的手机密码

作者: 火卫控 | 来源:发表于2021-10-29 15:48 被阅读0次

利用Python求解 小明的手机密码

问题:

小明5次输入手机密码均错误 ,每次输入的密码中有两位数字正确,但位置都不对。现求小明手机密码。 其中五次输入的密码如下: 6087 5173 1358 3825 2531

隐含条件: 四位数均不同


计算结果

算法实现

1.提取每位数字,去重,做出排列组合,
2 验证位置,获得密码

学习

python求解,数列运用列表集合的转换,以及嵌套循环的使用,条件判断的设置
将打印输出到txt,注意,要用GBK打开

计算结果为 8712 ,经验证正确

代码如下:

#!/usr/bin/env python
# -- coding = 'utf-8' --
# @Python  : 3.7
# @OS      : Windows 10 kiton.
# @Time    : 2021/10/29 12:55
# @Author  : 
# @E-mail  : 1154282938@qq.com
# @File    : 手机密码.py
# @Software: PyCharm
# 小明5次输入手机密码均错误 ,每次输入的密码中有两位数字正确,但位置都不对。现求小明手机密码
# 五次如下: 6087  5173  1358  3825  2531
# 隐含条件: 四位数均不相等
# 答案 为8712
# 算法实现 1.提取每位数字,去重,做出排列组合,2 验证位置,获得密码

# 将输入的密码提取出所有数字,去掉重复,排序后,依次生成四位数不同的待检密码
digit = []  # 将要放置提取数字的空列表
password_input = ['6087', '5173', '1358', '3825', '2531'] # 所有输入过的错误密码 生成列表

# 此代码块是为了将打印输出至文本文件中,方便分析查找
import sys
class Logger(object):
    def __init__(self, fileN='Default.log'):
        self.terminal = sys.stdout
        self.log = open(fileN, 'a')
    def write(self, message):
        '''print实际相当于sys.stdout.write'''
        self.terminal.write(message)
        self.log.write(message)
    def flush(self):
        pass
sys.stdout = Logger(r'./test.txt')


# 开始提取输入密码中的所有数字
for i in password_input:
    for j in i:
        digit.append(j)

# 去重, 转换成集合去重后再转回列表
digit = list(set(digit))
# 排序
digit.sort()
# 先预定义,正确手机密码,缺省为0
true_pwd = 0
# 预先定义待检密码的个数计数
daijian_pwd_num = 0
# 开始生成四位数字
for i in digit:
    for j in digit:
        for m in digit:
            for n in digit:
                # 将遍历的四个数字转成集合,便于后面判断是否全不相同
                daijian = set([i,j,m,n])
                # 获得四个不同数字的 四位数 待检验密码    字符串类型
                if len(daijian) == 4:
                    # 满足条件,拼成四位数字,为待检密码
                    pwd = i+j+m+n
                    daijian_pwd_num = daijian_pwd_num + 1
                    # 打印初步获取的待检密码
                    # print("----------------------------------------")
                    print("初步生成的第{}个待检密码为: ".format(daijian_pwd_num), pwd)



                    # 先将生成的四位数字转换为集合,方便后面做交集运算
                    s1 = set(list(pwd))
                    # 预设检验计数,每验证一次待检密码 归0
                    bool_counter = 0

                    # 遍历输入的密码,验证只有两位是对的,但位置不对
                    for k in password_input:  #
                        # 将输入的遍历的密码,转成集合,方便后面交集运算
                        s2 = set(list(k))
                        # 找出相同的数字
                        correct_digit = list(s1 & s2)  #列表 交集
                        # print("相同数字为:", correct_digit)
                        # 获得相同数字的个数
                        correct_num = len(correct_digit)  #列表 长度
                        # print("相同数字的个数为:" , correct_num)
                        # 判断相同数字为2
                        if correct_num == 2:
                            # 寻找相同的数字在待检和已输入密码列表中的索引,便于后判断是否相同,相同则不是真实密码
                            index1_pwd = pwd.index(correct_digit[0])
                            index2_pwd = pwd.index(correct_digit[1])
                            index1_k = k.index(correct_digit[0])
                            index2_k = k.index(correct_digit[1])
                            # 判断相同数字是否在不同位置
                            if (index1_k != index1_pwd) and (index2_k != index2_pwd):
                                bool_counter = bool_counter + 1
                    # 打印
                    print("五次输入密码中与待检密码有相同位置数字的个数为: ", 5-bool_counter,'\n----------------------------------------')
                    # 判断验证总计数是否为输入的错误密码次数,如是则为真实密码
                    if bool_counter == len(password_input):
                        # 当验证计数为5,即待检密码与此前输入的5个密码都是有两个数字相同但位置错误时,此为小明的真实手机密码
                        true_pwd = pwd
                        true_pwd_num = daijian_pwd_num

print("***初步生成的待检密码总共有: ", daijian_pwd_num," 个")
print("五次输入密码中与待检密码有相同位置数字的个数为0时,才是正确密码" +
      "\n   因此:")
print("     小明的手机密码为: -> ", true_pwd +"  <-\n     位于生成的待检密码的{}位".format(true_pwd_num))

打印结果如下:

D:\ruanjian\anaconda202002\python.exe F:/vscode-python-kiton/数学/数学小问题/手机密码.py
初步生成的第1个待检密码为:  0123
五次输入密码中与待检密码有相同位置数字的个数为:  4 
----------------------------------------
初步生成的第2个待检密码为:  0125
五次输入密码中与待检密码有相同位置数字的个数为:  4 
----------------------------------------
初步生成的第3个待检密码为:  0126
五次输入密码中与待检密码有相同位置数字的个数为:  3 
----------------------------------------
初步生成的第4个待检密码为:  0127
五次输入密码中与待检密码有相同位置数字的个数为:  4 
----------------------------------------
初步生成的第5个待检密码为:  0128
五次输入密码中与待检密码有相同位置数字的个数为:  3 
----------------------------------------
.
.

.

初步生成的第1655个待检密码为:  8706
五次输入密码中与待检密码有相同位置数字的个数为:  5 
----------------------------------------
初步生成的第1656个待检密码为:  8710
五次输入密码中与待检密码有相同位置数字的个数为:  3 
----------------------------------------
初步生成的第1657个待检密码为:  8712
五次输入密码中与待检密码有相同位置数字的个数为:  0 
----------------------------------------
初步生成的第1658个待检密码为:  8713
五次输入密码中与待检密码有相同位置数字的个数为:  2 
----------------------------------------
初步生成的第1659个待检密码为:  8715
五次输入密码中与待检密码有相同位置数字的个数为:  3 
----------------------------------------
初步生成的第1660个待检密码为:  8716
五次输入密码中与待检密码有相同位置数字的个数为:  3 
----------------------------------------
初步生成的第1661个待检密码为:  8720
五次输入密码中与待检密码有相同位置数字的个数为:  5 
----------------------------------------
.
.
.
----------------------------------------
初步生成的第1678个待检密码为:  8762
五次输入密码中与待检密码有相同位置数字的个数为:  4 
----------------------------------------
初步生成的第1679个待检密码为:  8763
五次输入密码中与待检密码有相同位置数字的个数为:  3 
----------------------------------------
初步生成的第1680个待检密码为:  8765
五次输入密码中与待检密码有相同位置数字的个数为:  3 
----------------------------------------
***初步生成的待检密码总共有:  1680  个
五次输入密码中与待检密码有相同位置数字的个数为0时,才是正确密码
   因此:
     小明的手机密码为: ->  8712  <-
     位于生成的待检密码的1657位

Process finished with exit code 0

相关文章

网友评论

      本文标题:利用Python求解 小明的手机密码

      本文链接:https://www.haomeiwen.com/subject/sbiialtx.html