2018最火刑侦题(Python constraint库求解)
程序员文章站
2022-05-07 08:02:12
...
最近特别火的2018年刑侦,反正我用笔做了半个小时没做出来。。咱先把题贴出来啊:
最后用人力搞不定的我选择了用python的constraint库求个答案。。
先大略的说下constraint库吧,其实简单说就是一个约束求解的库,用法如下:
problem = Problem()
problem.addVariable("a", [1,2,3])
problem.addVariable("b", [2,3,4,5])
def constrain(a, b):
return a == 1 or b == 2
problem.addConstraint(constrain,['a', 'b'])
print problem.getSolutions()
第一步先创建一个Problem对象;第二步向Problem里添加变量,比如第二行里的"a"可以理解为题目,[1, 2, 3]可以理解为a的三个可能的答案;第三步向Problem里添加约束条件,也就是我们写的constrain方法,然后把这个方法添加到Problem里。运行的结果如下:[{'a': 3, 'b': 2}, {'a': 2, 'b': 2}, {'a': 1, 'b': 5}, {'a': 1, 'b': 4}, {'a': 1, 'b': 3}, {'a': 1, 'b': 2}]
那么我们就开始做刑侦题了,直接贴代码吧:
# coding=utf-8
from constraint import *
problem = Problem()
problem.addVariables(['q1', 'q2', 'q3', 'q4', 'q5', 'q6', 'q7', 'q8', 'q9', 'q10'], [1, 2, 3, 4])
# 第2题约束,往后依次类推
def fun_q2(q2, q5):
return (q2 == 1 and q5 == 3) or (q2 == 2 and q5 == 4) or (q2 == 3 and q5 == 1) or (q2 == 4 and q5 == 2)
problem.addConstraint(fun_q2, ['q2', 'q5'])
def fun_q3(q3, q6, q2, q4):
return (q3 != q6 and q6 == q2 == q4) or (q6 != q3 and q3 == q2 == q4) or \
(q2 != q3 and q3 == q6 == q4) or (q4 != q3 and q3 == q6 == q2)
problem.addConstraint(fun_q3, ['q3', 'q6', 'q2', 'q4'])
def fun_q4(q1, q2, q5, q6, q7, q9, q10):
return (q1 == q5) or (q2 == q7) or (q1 == q9) or (q6 == q10)
problem.addConstraint(fun_q4, ['q1', 'q2', 'q5', 'q6', 'q7', 'q9', 'q10'])
def fun_q5(q5, q8, q4, q9, q7):
return (q5 == q8) or (q5 == q4) or (q5 == q9) or (q5 == q7)
problem.addConstraint(fun_q5, ['q5', 'q8', 'q4', 'q9', 'q7'])
def fun_q6(q1, q2, q3, q4, q5, q6, q8, q9, q10):
return ((q8 == q2 == q4) and q6 == 1) or ((q8 == q1 == q6) and q6 == 2) or \
((q8 == q3 == q10) and q6 == 3) or ((q8 == q5 == q9) and q6 == 4)
problem.addConstraint(fun_q6, ['q1', 'q2', 'q3', 'q4', 'q5', 'q6', 'q8', 'q9', 'q10'])
def fun_q7(q1, q2, q3, q4, q5, q6, q7, q8, q9, q10):
questionList = [q1, q2, q3, q4, q5, q6, q7, q8, q9, q10]
countList = [0, 0, 0, 0]
for question in questionList:
countList[question - 1] += 1
minQuestion = countList.index(min(countList)) + 1
return (q7 == 1 and minQuestion == 3) or (q7 == 2 and minQuestion == 2) or\
(q7 == 3 and minQuestion == 1) or (q7 == 4 and minQuestion == 4)
problem.addConstraint(fun_q7, ['q1', 'q2', 'q3', 'q4', 'q5', 'q6', 'q7', 'q8', 'q9', 'q10'])
def fun_q8(q1, q7, q5, q2, q10, q8):
return ((abs(q1-q7) > 1) and q8 == 1) or ((abs(q1-q5) > 1) and q8 == 2) or \
((abs(q1-q2) > 1) and q8 == 3) or ((abs(q1-q10) > 1) and q8 == 4)
problem.addConstraint(fun_q8, ['q1', 'q7', 'q5', 'q2', 'q10', 'q8'])
def fun_q9(q1, q6, q10, q2, q9, q5):
return (((q1 == q6) != (q6 == q5)) and q9 == 1) or (((q1 == q6) != (q10 == q5)) and q9 == 2) or\
(((q1 == q6) != (q2 == q5)) and q9 == 3) or (((q1 == q6) != (q9 == q5)) and q9 == 4)
problem.addConstraint(fun_q9, ['q1', 'q6', 'q10', 'q2', 'q9', 'q5'])
def fun_q10(q1, q2, q3, q4, q5, q6, q7, q8, q9, q10):
questionList = [q1, q2, q3, q4, q5, q6, q7, q8, q9, q10]
countList = [0, 0, 0, 0]
for question in questionList:
countList[question - 1] += 1
minValue = min(countList)
maxValue = max(countList)
x = maxValue - minValue
return (q10 == 1 and x == 3) or (q10 == 2 and x == 2) or (q10 == 3 and x == 4) or (q10 == 4 and x == 1)
problem.addConstraint(fun_q10, ['q1', 'q2', 'q3', 'q4', 'q5', 'q6', 'q7', 'q8', 'q9', 'q10'])
print problem.getSolutions()
只用一眨眼的时间答案就算出来了:[{'q1': 2, 'q3': 1, 'q2': 3, 'q5': 1, 'q4': 3, 'q7': 4, 'q6': 3, 'q9': 2, 'q8': 1, 'q10': 1}]
(qn代表第n题,1代表A,2代表B,......)