【Python实践】用穷举法解决推理难题

🌈据说,看我文章时 关注、点赞、收藏帅哥美女们 心情都会不自觉的好起来。

前言:
🧡作者简介:大家好我是 user_from_future ,意思是 “ 来自未来的用户 ” ,寓意着未来的自己一定很棒~
✨个人主页:点我直达,在这里肯定能找到你想要的~
👍专栏介绍:Python实践 ,一个很哇塞的专栏~

想看往期历史文章,可以浏览此博文: 历史文章目录,后续所有文章发布都会同步更新此博文~

人生苦短,我用python

前言

今天,翻到了以前刷到的一套《2018年刑侦推理试题》:
在这里插入图片描述
快速浏览了一遍,我直接CPU都烧了,完全不知道该从何下手,然后百度了一下,发现推理过程有那么亿点点复杂!【推理解析网站】 还没看完这个网站,我的脑细胞就死了一大片。
为了保护我的脑细胞,我决定用Python来处理这题。

完整题目

2018年刑侦科推理试题
单项选择,(每题10分,共100分)
1这道题的答案是:
A.A B.B C.C D.D
2.第5题的答案是:
A.C B.D C.A D.B
3.以下选项中哪-题的答案与其他三项不同:
A.第3题 B.第6题 C.第2题 D.第4题
4.以下选项中哪两题的答案相同:
A.第1,5题 B.第2,9题 C.第1,9题 D.第6,10题
5.以下选项中哪一题的答案与本题相同:
A.第8题 B.第4题 C.第9题 D.第9题
6.以下选项中哪两题的答案与第8题相同:
A.第2,4题 B.第1,6题 C.第3,10题 D.第5,9题
9.在此十道题中,被选中次数最少的选项字母为:
A.C B.B C.A D.D
8.以下选项中哪-题的答案 与第1题的答案在字母中不相邻:
A.第9题 B.第5题 C.第2题 D.第10题
9.已知“第1题与第6题的答案相同”与"第X题与第5题的答案相同”的真假性相反,那么X为:
A.第6题 B.第10题 C.第2题 D.第9题
10.在此10道题中,ABCD四个字母出现次数最多与最少者的差为:
A.3 B.2 C.4 D.1

简述

推理实际上是先进行线索之间的联系梳理,然后再对符合线索的可能进行穷举判断,对于CPU比较菜的我来说,不如完全穷举,然后一题一题的判断出来。
于是我们的代码结构应该是这样的:

def make_answers(scope, length):
	"""
	生成答案
	"""
	pass


def check_answer(ans):
	"""
	检查答案
	"""
	pass


for answer in make_answers(['A', 'B', 'C', 'D'], 10):
    if check_answer(answer):
        print(answer)
        break

生成答案

由于我们的答案相当于有 410 种,不方便用普通的循环写,所以我们这里使用递归生成答案:

def make_answers(scope, length, ans=''):
	"""
	生成答案
	"""
    if length > 0:
        for s in scope:
            yield from make_answers(scope=scope, length=length - 1, ans=ans + s)
    else:
        yield ans

这样我们就能穷举出所有的答案了,穷举完之后,你可以添加一些过滤,比如全A、全B、全C、全D的,肯定不可能是最终答案。

检查答案

在这里,实际上就是一题一题往上写。由于第一题是开放的,所以由第二题开始写条件。

第二题

2.第5题的答案是:
A.C B.D C.A D.B

(ans[1] == 'A' and ans[4] == 'C') \
 or (ans[1] == 'B' and ans[4] == 'D') \
 or (ans[1] == 'C' and ans[4] == 'A') \
 or (ans[1] == 'D' and ans[4] == 'B')

第三题

3.以下选项中哪-题的答案与其他三项不同:
A.第3题 B.第6题 C.第2题 D.第4题

(ans[2] == 'A' and {ans[5], ans[1], ans[3]} == {ans[5]} and ans[2] != ans[5]) \
or (ans[2]=='B'and{ans[2], ans[1], ans[3]} == {ans[2]} and ans[5] != ans[2]) \
or (ans[2] == 'C' and {ans[2], ans[5], ans[3]} == {ans[2]} and ans[1] != ans[2]) \
or (ans[2] == 'D' and {ans[2], ans[5], ans[1]} == {ans[2]} and ans[3] != ans[2])

第四题

4.以下选项中哪两题的答案相同:
A.第1,5题 B.第2,9题 C.第1,9题 D.第6,10题

(ans[3] == 'A' and ans[0] == ans[4]) \
or (ans[3] == 'B'andans[1]==ans[6]) \
or (ans[3] == 'C' and ans[0] == ans[8]) \
or (ans[3] == 'D' and ans[5] == ans[9])

第五题

5.以下选项中哪一题的答案与本题相同:
A.第8题 B.第4题 C.第9题 D.第9题

(ans[4] == 'A' and ans[4] == ans[9]) \
or (ans[4]== 'B'andans[4] == ans[3]) \
or (ans[4] == 'C' and ans[4] == ans[8]) \
or (ans[4] == 'D' and ans[4] == ans[6])

第六题

6.以下选项中哪两题的答案与第8题相同:
A.第2,4题 B.第1,6题 C.第3,10题 D.第5,9题

(ans[5] == 'A' and {ans[1], ans[3]} == {ans[7]}) \
or (ans[5]== 'B'and{ans[0], ans[5]} == {ans[7]}) \
or (ans[5] == 'C' and {ans[2], ans[9]} == {ans[7]}) \
or (ans[5] == 'D' and {ans[4], ans[8]} == {ans[7]})

第七题

9.在此十道题中,被选中次数最少的选项字母为:
A.C B.B C.A D.D

选项次数排序

ans_count ={a: ans.count(a) for a in set(ans)}
ans_count_sorted = sorted(['A', 'B', 'C', 'D'], key=lambda key: ans_count.get(key, 0))
(ans[6] == 'A' and ans_count_sorted[0] == 'C') \
or (ans[6]=='B'andans_count_sorted[0] == 'B') \
or (ans[6] == 'C' and ans_count_sorted[0] == 'A') \
or (ans[6] == 'D' and ans_count_sorted[0] == 'D')

第八题

8.以下选项中哪-题的答案 与第1题的答案在字母中不相邻:
A.第9题 B.第5题 C.第2题 D.第10题

(ans[7] == 'A' and (ans[1] + ans[7]) not in ['AB', 'BA', 'BC', 'CB', 'CD', 'DC']) \
or (ans[7]=='B'and(ans[1] + ans[7]) not in ['AB', 'BA', 'BC', 'CB', 'CD', 'DC']) \
or (ans[7] == 'C' and (ans[1] + ans[7]) not in ['AB', 'BA', 'BC', 'CB', 'CD', 'DC']) \
or (ans[7] == 'D' and (ans[1] + ans[7]) not in ['AB', 'BA', 'BC', 'CB', 'CD', 'DC'])

第九题

9.已知“第1题与第6题的答案相同”与"第X题与第5题的答案相同”的真假性相反,那么X为:
A.第6题 B.第10题 C.第2题 D.第9题

(ans[8] == 'A' and (ans[0] == ans[5]) != (ans[4] == ans[5])) \
or (ans[8]=='B'and(ans[0] == ans[5]) != (ans[4] == ans[9])) \
or (ans[8] == 'C' and (ans[0] == ans[5]) != (ans[4] == ans[1])) \
or (ans[8] == 'D' and (ans[0] == ans[5]) != (ans[4] == ans[8]))

第十题

10.在此10道题中,ABCD四个字母出现次数最多与最少者的差为:
A.3 B.2 C.4 D.1

选项次数排序

ans_count ={a: ans.count(a) for a in set(ans)}
ans_count_sorted = sorted(['A', 'B', 'C', 'D'], key=lambda key: ans_count.get(key, 0))
(ans[9] == 'A' and ans_count[ans_count_sorted[-1]] - ans_count[ans_count_sorted[0]] == 3) \
or (ans[9]=='B'and ans_count[ans_count_sorted[-1]] - ans_count[ans_count_sorted[0]] == 2) \
or (ans[9] == 'C' and ans_count[ans_count_sorted[-1]] - ans_count[ans_count_sorted[0]] == 4) \
or (ans[9] == 'D' and ans_count[ans_count_sorted[-1]] - ans_count[ans_count_sorted[0]] == 1)

综合

集体加个 not ,有一项不满足就返回 False ,全通过返回 True

def check_answer(ans):
    """
    检查答案
    """
    ans_count = {a: ans.count(a) for a in set(ans)}
    ans_count_sorted = sorted(['A', 'B', 'C', 'D'], key=lambda key: ans_count.get(key, 0))
    if not ((ans[1] == 'A' and ans[4] == 'C')
            or (ans[1] == 'B' and ans[4] == 'D')
            or (ans[1] == 'C' and ans[4] == 'A')
            or (ans[1] == 'D' and ans[4] == 'B')):
        return False
    if not ((ans[2] == 'A' and {ans[5], ans[1], ans[3]} == {ans[5]} and ans[2] != ans[5])
            or (ans[2] == 'B' and {ans[2], ans[1], ans[3]} == {ans[2]} and ans[5] != ans[2])
            or (ans[2] == 'C' and {ans[2], ans[5], ans[3]} == {ans[2]} and ans[1] != ans[2])
            or (ans[2] == 'D' and {ans[2], ans[5], ans[1]} == {ans[2]} and ans[3] != ans[2])):
        return False
    if not ((ans[3] == 'A' and ans[0] == ans[4])
            or (ans[3] == 'B' and ans[1] == ans[6])
            or (ans[3] == 'C' and ans[0] == ans[8])
            or (ans[3] == 'D' and ans[5] == ans[9])):
        return False
    if not ((ans[4] == 'A' and ans[4] == ans[9])
            or (ans[4] == 'B' and ans[4] == ans[3])
            or (ans[4] == 'C' and ans[4] == ans[8])
            or (ans[4] == 'D' and ans[4] == ans[6])):
        return False
    if not ((ans[5] == 'A' and {ans[1], ans[3]} == {ans[7]})
            or (ans[5] == 'B' and {ans[0], ans[5]} == {ans[7]})
            or (ans[5] == 'C' and {ans[2], ans[9]} == {ans[7]})
            or (ans[5] == 'D' and {ans[4], ans[8]} == {ans[7]})):
        return False
    if not ((ans[6] == 'A' and ans_count_sorted[0] == 'C')
            or (ans[6] == 'B' and ans_count_sorted[0] == 'B')
            or (ans[6] == 'C' and ans_count_sorted[0] == 'A')
            or (ans[6] == 'D' and ans_count_sorted[0] == 'D')):
        return False
    if not ((ans[7] == 'A' and (ans[1] + ans[7]) not in ['AB', 'BA', 'BC', 'CB', 'CD', 'DC'])
            or (ans[7] == 'B' and (ans[1] + ans[7]) not in ['AB', 'BA', 'BC', 'CB', 'CD', 'DC'])
            or (ans[7] == 'C' and (ans[1] + ans[7]) not in ['AB', 'BA', 'BC', 'CB', 'CD', 'DC'])
            or (ans[7] == 'D' and (ans[1] + ans[7]) not in ['AB', 'BA', 'BC', 'CB', 'CD', 'DC'])):
        return False
    if not ((ans[8] == 'A' and (ans[0] == ans[5]) != (ans[4] == ans[5]))
            or (ans[8] == 'B' and (ans[0] == ans[5]) != (ans[4] == ans[9]))
            or (ans[8] == 'C' and (ans[0] == ans[5]) != (ans[4] == ans[1]))
            or (ans[8] == 'D' and (ans[0] == ans[5]) != (ans[4] == ans[8]))):
        return False
    if not ((ans[9] == 'A' and ans_count[ans_count_sorted[-1]] - ans_count[ans_count_sorted[0]] == 3)
            or (ans[9] == 'B' and ans_count[ans_count_sorted[-1]] - ans_count[ans_count_sorted[0]] == 2)
            or (ans[9] == 'C' and ans_count[ans_count_sorted[-1]] - ans_count[ans_count_sorted[0]] == 4)
            or (ans[9] == 'D' and ans_count[ans_count_sorted[-1]] - ans_count[ans_count_sorted[0]] == 1)):
        return False
    return True

完整代码

def make_answers(scope, length, ans=''):
    """
    生成答案
    """
    if length > 0:
        for s in scope:
            yield from make_answers(scope=scope, length=length - 1, ans=ans + s)
    else:
        yield ans


def check_answer(ans):
    """
    检查答案
    """
    ans_count = {a: ans.count(a) for a in set(ans)}
    ans_count_sorted = sorted(['A', 'B', 'C', 'D'], key=lambda key: ans_count.get(key, 0))
    if not ((ans[1] == 'A' and ans[4] == 'C')
            or (ans[1] == 'B' and ans[4] == 'D')
            or (ans[1] == 'C' and ans[4] == 'A')
            or (ans[1] == 'D' and ans[4] == 'B')):
        return False
    if not ((ans[2] == 'A' and {ans[5], ans[1], ans[3]} == {ans[5]} and ans[2] != ans[5])
            or (ans[2] == 'B' and {ans[2], ans[1], ans[3]} == {ans[2]} and ans[5] != ans[2])
            or (ans[2] == 'C' and {ans[2], ans[5], ans[3]} == {ans[2]} and ans[1] != ans[2])
            or (ans[2] == 'D' and {ans[2], ans[5], ans[1]} == {ans[2]} and ans[3] != ans[2])):
        return False
    if not ((ans[3] == 'A' and ans[0] == ans[4])
            or (ans[3] == 'B' and ans[1] == ans[6])
            or (ans[3] == 'C' and ans[0] == ans[8])
            or (ans[3] == 'D' and ans[5] == ans[9])):
        return False
    if not ((ans[4] == 'A' and ans[4] == ans[9])
            or (ans[4] == 'B' and ans[4] == ans[3])
            or (ans[4] == 'C' and ans[4] == ans[8])
            or (ans[4] == 'D' and ans[4] == ans[6])):
        return False
    if not ((ans[5] == 'A' and {ans[1], ans[3]} == {ans[7]})
            or (ans[5] == 'B' and {ans[0], ans[5]} == {ans[7]})
            or (ans[5] == 'C' and {ans[2], ans[9]} == {ans[7]})
            or (ans[5] == 'D' and {ans[4], ans[8]} == {ans[7]})):
        return False
    if not ((ans[6] == 'A' and ans_count_sorted[0] == 'C')
            or (ans[6] == 'B' and ans_count_sorted[0] == 'B')
            or (ans[6] == 'C' and ans_count_sorted[0] == 'A')
            or (ans[6] == 'D' and ans_count_sorted[0] == 'D')):
        return False
    if not ((ans[7] == 'A' and (ans[1] + ans[7]) not in ['AB', 'BA', 'BC', 'CB', 'CD', 'DC'])
            or (ans[7] == 'B' and (ans[1] + ans[7]) not in ['AB', 'BA', 'BC', 'CB', 'CD', 'DC'])
            or (ans[7] == 'C' and (ans[1] + ans[7]) not in ['AB', 'BA', 'BC', 'CB', 'CD', 'DC'])
            or (ans[7] == 'D' and (ans[1] + ans[7]) not in ['AB', 'BA', 'BC', 'CB', 'CD', 'DC'])):
        return False
    if not ((ans[8] == 'A' and (ans[0] == ans[5]) != (ans[4] == ans[5]))
            or (ans[8] == 'B' and (ans[0] == ans[5]) != (ans[4] == ans[9]))
            or (ans[8] == 'C' and (ans[0] == ans[5]) != (ans[4] == ans[1]))
            or (ans[8] == 'D' and (ans[0] == ans[5]) != (ans[4] == ans[8]))):
        return False
    if not ((ans[9] == 'A' and ans_count[ans_count_sorted[-1]] - ans_count[ans_count_sorted[0]] == 3)
            or (ans[9] == 'B' and ans_count[ans_count_sorted[-1]] - ans_count[ans_count_sorted[0]] == 2)
            or (ans[9] == 'C' and ans_count[ans_count_sorted[-1]] - ans_count[ans_count_sorted[0]] == 4)
            or (ans[9] == 'D' and ans_count[ans_count_sorted[-1]] - ans_count[ans_count_sorted[0]] == 1)):
        return False
    return True


for answer in make_answers(['A', 'B', 'C', 'D'], 10):
    if check_answer(answer):
        print(answer)
        break

结语

电脑运行快的估计 1s 就运行出来了吧,慢的最多也就 2s-3s 的样子。
虽然敲的码量稍微有点多,可能敲完代码,会推理的都已经推理完了。
不过代码我并没有设计过,否则代码可以简化不少,运行也可能更快。
但是!由于代码是按照题目条件写的,都不用动脑。
所以本次穷举答案我宣布,脑细胞死了 0 个!

  • 27
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.项目代码均经过功能验证ok,确保稳定可靠运行。欢迎下载体验!下载完使用问题请私信沟通。 2.主要针对各个计算机相关专业,包括计算机科学、信息安全、数据科学与大数据技术、人工智能、通信、物联网等领域的在校学生、专业教师、企业员工。 3.项目具有丰富的拓展空间,不仅可作为入门进阶,也可直接作为毕设、课程设计、大作业、初期项目立项演示等用途。 4.当然也鼓励大家基于此进行二次开发。在使用过程中,如有问题或建议,请及时沟通。 5.期待你能在项目中找到乐趣和灵感,也欢迎你的分享和反馈! 【资源说明】 基于Python的字典穷举法WiFi密码安全性测试源码+使用教程+超详细注释.zip 功能 - 字典爆破测试连接WiFi(字典生成可以自行修改,自由发挥) - 找回忘记的密码(演示中只能找回简单密码,如8位数的数字密码,需要复杂密码自己改) - 用于测试自己家路由器WiFi密码设置的安全性(是否很轻易被破解) 使用说明 如何安装、配置、使用本项目。 首先需要[安装python3](https://python.org/) 然后安装pywifi模块 ``` python pip install pywifi ``` 在使用前,请注意,这个项目进用于学习交流和娱乐,请勿用于非法途径 示例 先运行字典生成.py文件(代码可以改,自由发挥,但请确保不用于非法用途) 然后运行wifi-dictionaryer.py文件,加载文件(选择刚刚生成的那个字典文件) 即可自动开始测试
好的,可以的。那我们先来了解一下什么是任务指派问题。 任务指派问题是指在一定的约束条件下,将n个任务分配给n个人员,使得完成这些任务所需的总成本最小。这种问题也称为最优任务分配问题,是经典的运筹学问题之一。 对于这个问题,穷举法是一种比较直接的解决方法。具体步骤如下: 1. 首先,需要定义一个函数来计算当前任务分配的总成本。这个函数需要输入一个n x n的矩阵,表示每个人员完成每个任务所需的成本。 2. 接着,需要编写一个嵌套循环,来穷举所有可能的任务分配方案。在循环中,需要记录当前的最小成本,并更新最小成本的任务分配方案。 3. 最后,返回最小成本和任务分配方案。 下面是一个简单的示例代码,仅供参考: ``` import itertools def assign_tasks(cost_matrix): n = len(cost_matrix) min_cost = float('inf') min_assignment = None for assignment in itertools.permutations(range(n)): total_cost = 0 for i in range(n): total_cost += cost_matrix[i][assignment[i]] if total_cost < min_cost: min_cost = total_cost min_assignment = assignment return min_cost, min_assignment ``` 在上面的代码中,我们使用了 itertools.permutations 函数来穷举所有可能的任务分配方案。然后,我们计算每个方案的总成本,并更新最小成本和任务分配方案。 需要注意的是,这种穷举法解决任务指派问题的时间复杂度为 O(n!),当n较大时,计算量会非常大。因此,在实际应用中,需要考虑其他更高效的算法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值