这道逻辑题 用 Python 代码 如何实现?

2021-01-15 18:29:35 +08:00
 dwadewyp
1.第一个答案是 A 的问题是哪一个?  ()
	A:1  B:2  C:3  D:4

2.唯一的连续两个具有相同答案的问题是 ()
	A:5,6  B:6,7  C:7,8  D:8,9

3.本问题答案和哪一个问题的答案相同 ()
	A:4  B:9  C:8  D:2

4.答案是 A 的问题的个数是 ()
	A:5  B:4  C:3  D:2 

5.本问题答案和哪一个问题的答案相同 ()
	A:1  B:2  C:3  D:4

6.答案选 A 的问题的个数和答案选什么的问题的个数相同 ()	
	A:无  B:C  C:C  D:D

7.按照字母顺序, 本题答案与下一题相差 () {A 与 B 间,或 B 与 A 间均相差 1}
	A:3  B:2  C:1  D:0

8.十道题中答案为元音的题数为 ()
	A:0  B:1  C:2  D:3

9.十道题中答案为辅音的题数为 ()
	A:是合数  B:是质数  C:<5  D:是平方数

10.本题答案为 ()
	A:A  B:B  C:C  D:D
3210 次点击
所在节点    Python
25 条回复
imn1
2021-01-15 18:44:40 +08:00
有趣
先确定一下,你说的是解题吧?

跟什么语言无关,主要难题是问题的语义要准确翻译到逻辑式
穷举肯定是可以的,逻辑判断解法就要想了……
XiaoxiaoPu
2021-01-15 18:47:52 +08:00
可以类似解数独的方式去做,只不过各个格子(各个问题)的合法性判断不是统一的规则,而是 10 个不同的逻辑。
把这 10 个问题 “翻译” 成判定代码,可能是最繁琐的事情了。
superrichman
2021-01-15 18:47:54 +08:00
穷举,要优化也就调整一下题目验证顺序
dwadewyp
2021-01-15 18:51:49 +08:00
@imn1 确实和语言无关, 主要是在于思路
XiaoxiaoPu
2021-01-15 18:56:32 +08:00
第一个问题可以翻译成下面的函数,answers 是一个长度为 10 的 list

def q1(answers):
𑑛𑑛𑑛𑑛for i in range(4):
𑑛𑑛𑑛𑑛𑑛𑑛𑑛𑑛if answers[i] == 'A':
𑑛𑑛𑑛𑑛𑑛𑑛𑑛𑑛𑑛𑑛𑑛𑑛return answers[0] == 'ABCD'[i]
𑑛𑑛𑑛𑑛return False
lithiumii
2021-01-15 19:32:52 +08:00
笨办法:先按 10 道题的要求写测试,然后穷举,直到能通过测试
dwadewyp
2021-01-15 20:47:51 +08:00
我想知道 如果用穷举的话, 代码实现怎么实现呢?
zhuangzhuang1988
2021-01-15 20:50:59 +08:00
washbrain
2021-01-15 21:07:38 +08:00
用 python 做的话应该就是 DFS 了,类似数独的思想去做就行,优化就是剪枝啥的
不过这种逻辑推理题其实最合适的是直接用 prolog 做推理,你把规则和事实告诉程序,让机器去帮你推理,当然背后本质也是搜索那一套
hello2060
2021-01-15 21:25:01 +08:00
@dwadewyp

answer = new list

Getanswer(pos:0, answer) {
if (pos 越界) return
// 检查 answer 里所有现有答案逻辑是否一致,不一致返回

for (int i = 0; i < 4; I++) {
answer.push(I)
getanswer(pos + 1, answer)
answer.poplast()
}
}
dwadewyp
2021-01-15 21:35:34 +08:00
@washbrain 能否细说下 如果 dfs 的话,这棵树如何构建?
dwadewyp
2021-01-15 21:43:44 +08:00
@zhuangzhuang1988 这个通用模版 学习到了, 感谢!
dwadewyp
2021-01-15 22:49:03 +08:00
@zhuangzhuang1988 我刚才把约束满足问题框架读了一遍,不过本人愚笨,写不出我提出的这个问题的约束条件,大佬能否点拨一下?
dwadewyp
2021-01-15 23:05:44 +08:00
@washbrain 回溯思路: 一旦在搜索中碰到障碍,就会回到碰到障碍之前的最后一次做出判断的已知点, 然后选择其他一条路径(可以理解为递归式的深度优先搜索); ps:其实我在推演的过程中, 就想到了这是典型的回溯递归 dfs ;只是编码起来 有点难 😄。。。
imn1
2021-01-15 23:31:02 +08:00
@dwadewyp #7
穷举的话
每题写一个逻辑表达式
把答案排列组合写出来,逐个去测试逻辑表达式,遇到 False 就 continue 测试下一个,直到 10 题 all True 就是正解
例如 10 个 A,第二题答案 A 就 False 了,('A'*10).find('AA')==5 --> False,当然第二题的逻辑式不是 find 这么简单,只是举例而已
imn1
2021-01-15 23:34:07 +08:00
@dwadewyp
呃,楼上应该是==4,第一题序号为 0,大致意思,看得明就行
dwadewyp
2021-01-15 23:56:17 +08:00
@imn1 穷举的大致思路明白了 谢谢, 我在想一下 每一个测试的逻辑表达式,该如何写
Dvel
2021-01-16 00:32:57 +08:00
@dwadewyp #17 每题写一个函数,每个函数写 4 个 if,每个 if 返回一个 bool,这样逻辑清晰,就是逻辑繁杂写着麻烦。
wuyamao
2021-01-16 01:02:09 +08:00
if Ans1 == 1 or (Ans1==2 and Ans2==1) or (Ans1==3 and Ans2!=1 and Ans3==1) or (Ans1==4 and Ans2!=1 and Ans3!=1 and Ans1==1):
if (Ans2 == 1 and Ans5==Ans6 and Ans1 != Ans2 and Ans2 != Ans3 and Ans3 != Ans4 and Ans4 != Ans5 and Ans6 != Ans7 and Ans7 != Ans8 and Ans8 != Ans9 and Ans9 != Ans10) or (Ans2 == 2 and Ans6==Ans7 and Ans1 != Ans2 and Ans2 != Ans3 and Ans3 != Ans4 and Ans4 != Ans5 and Ans5 != Ans6 and Ans7 != Ans8 and Ans8 != Ans9 and Ans9 != Ans10) or (Ans2 == 3 and Ans8==Ans7 and Ans1 != Ans2 and Ans2 != Ans3 and Ans3 != Ans4 and Ans4 != Ans5 and Ans6 != Ans7 and Ans5 != Ans6 and Ans8 != Ans9 and Ans9 != Ans10) or (Ans2 == 4 and Ans8==Ans9 and Ans1 != Ans2 and Ans2 != Ans3 and Ans3 != Ans4 and Ans4 != Ans5 and Ans6 != Ans7 and Ans5 != Ans6 and Ans9 != Ans10):
if (Ans3 == 1 and Ans4==1) or (Ans3 == 2 and Ans9==2) or (Ans3 == 3 and Ans8==3)or (Ans3 == 4 and Ans2==4):
countA = count(1,Ans1,Ans2,Ans3,Ans4,Ans5,Ans6,Ans7,Ans8,Ans9,Ans10)
if (Ans4 == 3 and countA == 3 ) or (Ans4 == 4 and countA ==2 ):
if (Ans5 == 1 and Ans1==1) or (Ans5 == 2 and Ans2==2) or (Ans5 == 3 and Ans3==3)or (Ans5 == 4 and Ans4==4):
countB = count(2,Ans1,Ans2,Ans3,Ans4,Ans5,Ans6,Ans7,Ans8,Ans9,Ans10)
countC = count(3,Ans1,Ans2,Ans3,Ans4,Ans5,Ans6,Ans7,Ans8,Ans9,Ans10)
countD = count(4,Ans1,Ans2,Ans3,Ans4,Ans5,Ans6,Ans7,Ans8,Ans9,Ans10)
if (Ans6 == 1 and countA != countB and countA != countC and countA != countD) or (Ans6 == 2 and countA == countC and countA != countD) or (Ans6 == 3 and countA == countC and countA != countD) or (Ans6 == 4 and countA == countD and countA != countC):
if (Ans7 == 1 and abs(Ans7-Ans8)==3) or (Ans7 == 2 and abs(Ans7-Ans8)==2) or (Ans7 == 3 and abs(Ans7-Ans8)==1)or (Ans7 == 4 and Ans8==4):
if (Ans8 == 3 and Ans4 == 4) or (Ans8 == 4 and Ans4 == 3):
countBCD = 10 - countA
if (Ans9==1 and (countBCD in [6,8])) or (Ans9==2 and (countBCD in [5,7])) or (Ans9==4 and countBCD ==9 ):


自己排版吧,可能有些有点漏
Lightbright
2021-01-16 06:57:22 +08:00
也就 100 多万种可能,暴力枚举一下(🐶

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/745338

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX