利用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
网友评论