一道逻辑推理题的程序实现(纯属娱乐)

 

一份逻辑推理题的程序求解(纯属自娱自乐)

 

闲来无聊,看到 QQ空间上转载了一份变态推理题的,至少表示我看了十多分钟无处下手,认识的人中有大神居然真的做出来了。。。我不知道他是们那么做的,不过作为编程爱好者,我第一时间想到的是写个程序把答案找出来(不要吐槽)。于是我就动手了。。。不过,这个简单的还是花了我2个小时。。。

 

下面,先给大家看一看题目:


这十道题可谓丧心病狂,因为题目答案高度关联,居然出现了多少个A多少个B这样的选项,不做完全卷根本不知道每道题对错。。。我简单分析了一下,也只看出切入点大概在第七八九题和第二题的样子吧,简单的分析就可以大概知道答案整体的A选项数量,然后慢慢推,不过期间貌似也有好几步要靠试才能试出来。。。。

 

我承认我没有那推理能力,所以我想到了用一个小程序。。。十层循环遍历所有可能方案,然后用十层判断过滤方案,找到正确答案。

 

我的程序是用python写的,用0 1 2 3 来代表ABCD,每层循环变量的取值就代表了每道题的答案,构建一个当前方案t_result,比如i0 = 1 i1 = 0 就对应着第一题选B第二题选A。遍历十层的效果就是这样,

 

 

考虑到可能结果不止一个,我另外定义一个叫final_result的列表来保存所有符合要求的结果。

 

然后是按照题目要求进行规则判断,即进行十层(实际只有九层)if判断来遍历所有方案,得到符合要求的结果,一旦某一环节不符合就由continue语句跳出当前结果,进入下一轮,一直留到最后的就是正确结果了!

每道题具体分析与对应的代码如下:

 

1、第一个答案是A的题目是哪个?()

 A、1 B、2 C、3 D、4

 

对第一道题的约束条件,我使用了for循环找到当前方案中第一个答案是A的题目序号,并与第一题答案对应的题目进行比较,选项一致的才能通过进入下一层过滤。由于观察发现ABCD选项答案对应的index序号且与ABCD的表示相等,所以最后的判断可以直接简化为比较答案序号与答案,如:当前方案第一题选A,那么第一道选A的题正好就是第一题,通过。

#规则一:第一个答案是A的结果
index = 0
for each_answer in t_result:
   if each_answer == 0:
        break
    else:
        if index < 4:
            index+=1
#print '第一个答案是A的题是:',index+1    
if not (t_result[index] == index):
     #print '不符合第一条'
     continue
else:
#规则二:唯一具有两个相同答案的问题:……

       

      2、唯一两个具有连续相同答案的问题是:()

        A、5,6  B、6,7  C、7,.8 D、8,9

   

    对于第二题,要求找到唯一两个连续相同答案,所以我另写了一个方法find_same_answer,来得到有连续相同答案的个数。

#寻找有相同答案问题的方法
def find_same_answer(result):
    count = 0
    for i in range(9):
        if result[i] == result[i+1]:
            count += 1
    return count

 

    只有连续相同答案个数为1,并且它的位置正好出先在当前方案答案对应的位置,才能通过。如:当前方案选B,find_same_answer返回1,而第6,7题结果恰好相等,且方案通过。

#规则二:唯一具有两个连续相同答案的问题:
if not ((find_same_answer(t_result) == 1) and ((t_result[1] == 0 and t_result[4] == t_result[5]) or \
          (t_result[1] == 1 and t_result[5] == t_result[6]) or \
          (t_result[1] == 2 and t_result[6] == t_result[7]) or \
          (t_result[1] == 3 and t_result[7] == t_result[8]))):
                  #print '不符合第二条'
                   continue
else:
     #规则三:本问题与哪个问题答案相同……

     

     3、本问题答案与那一个问题答案相同?()

           A、4  B、9  C、8  D、2

 

    这题相对容易些,只要判断第三题答案是否与选项对应的题目答案相同即可。、

#规则三:本问题与哪个问题答案相同
if not ((t_result[2] == 0 and t_result[2] == t_result[3]) or\
         (t_result[2] == 1 and t_result[2] == t_result[8]) or\
         (t_result[2] == 2 and t_result[2] == t_result[7]) or\
         (t_result[2] == 3 and t_result[2] == t_result[1]) ):
         #print '不符合第三条'
         continue
else:
       #规则四:答案是A的个数……

  

    4、答案是A的问题个数是:()

       A、5  B、4  C、3  D、2

 

   为了搞定这道题并方便后面的判断,我又写了一个函数X_count,来计算当前方案中答案为X的题目个数:

#计算答案是X的个数的方法:
def X_count(result,x):
    count = 0
    for each in result:
        if each == x:
            count += 1
    return count        

 

    如果对应的选项答案符合,就可以通过。

 

#规则四:答案是A的个数
if not ((t_result[3] == 0 and X_count(t_result,0) == 5) or\
         (t_result[3] == 1 and X_count(t_result,0) == 4) or\
         (t_result[3] == 2 and X_count(t_result,0) == 3) or\
         (t_result[3] == 3 and X_count(t_result,0) == 2) ):
                #print '不符合第四条'
                continue
else:
      #规则五:本问题与哪个问题答案相同……

  

5、本问题答案与那一道题问题答案相同?()

      A、1  B、2  C、3  D、4

 

    这道题也好说,只要判断选项是否成立即可 

#规则五:本问题与哪个问题答案相同
if not ((t_result[4] == 0 and t_result[4] == t_result[0]) or\
         (t_result[4] == 1 and t_result[4] == t_result[1]) or\
         (t_result[4] == 2 and t_result[4] == t_result[2]) or\
         (t_result[4] == 3 and t_result[4] == t_result[3]) ):
               #print '不符合第五条'
                continue
else:
       #规则六:选A问题个数与选什么的问题个数相同……

   

    6、答案选A的问题个数与答案选胜的的问题个数相等?()

        A、无      B、C      C、C        D、D

 

   借用X_count方法,道题的判断不难实现,遇上一题类似,只不过对于选项A、无,要麻烦一些,确保选A的个数与选BCD的个数都不相同。

#规则六:选A问题个数与选什么的问题个数相同
if not ((t_result[5] == 0 and not((X_count(t_result,0) == X_count(t_result,1)) or\
                                                (X_count(t_result,0) == X_count(t_result,2)) or\
                                                (X_count(t_result,0) == X_count(t_result,3)))) or\
          (t_result[5] == 1 and X_count(t_result,0) == X_count(t_result,2)) or\
          (t_result[5] == 2 and X_count(t_result,0) == X_count(t_result,2)) or\
          (t_result[5] == 1 and X_count(t_result,0) == X_count(t_result,3)) ):
              #print '不符合第六条'
              continue
else:
       #规则七:与下一题相差……

  

    7、按照字母顺序,本题答案与下一题相差()(A与B间,B与A间都差1)

          A、3  B、2   C、1  D、0

 

   这道题如果直接按照题目描述,判断条件会很麻烦,还涉及到求绝对值,所以我进行了简单的分析,发现第7题选A的话下一题(第8题)只能选D,选B的话下一题只能选D,选C的话下一题可选A或D,选D的话下一题也只能选D,所以得到这道题的判断条件:

#规则七:与下一题相差
if not ((t_result[6] == 0 and t_result[7] == 3) or\
         (t_result[6] == 1 and t_result[7] == 3) or\
         (t_result[6] == 2 and (t_result[7] == 3 or t_result[7] == 1))or\
         (t_result[6] == 3 and t_result[7] == 3) ):
               #print '不符合第七条'
                continue
else:
        #规则八、九:十道题中元音题数目……

    8、十道题中答案为元音的题目数为()

         A、0  B、1  C、2  D、3

    9、是道题中答案为辅音的题目数为()

        A、是合数  B、是质数   C、<= 5   D、是平方数

 

   这两道题虽然看起来很吓人,不过其实如果稍加分析的话,可以排除很多答案,完全可以作为解整份题的突破点。

  首先,元音只有A,辅音为BCD。第八题决定了选元音答案(即A)的数只能为0 1 2 3 ,那么第九题中辅音答案(BCD)个数也只能为7 8 9 10,不可能小于等于5,第九题C排除,而这四个数中8 9 10为合数,9又为平方数,所以第九题选D那么A也正确,因此第九题D也排除,又因为第一题就决定了题目中有A选项,所以第八题不选A而辅音数为7 或 8,所以这两道题只剩两种情况可选:辅音数为7,8选D 9选B;或者辅音数为8,8选C 9选A。因此判断条件也就简化了:

#规则八、九:十道题中元音题数目
if not ((t_result[7] == 2 and X_count(t_result,0) == 2) or\
        (t_result[7] == 3 and X_count(t_result,0) == 3)):
             #print '不符合第八九条'
             continue
else:
     print '得到了一个结果!'                     

    10、本题答案为()

        A、A      B、B     C、C     D、D

    这道题明显属于打酱油,答案完全取决于之前的九道题目,不管选什么,只要使得之前的九道题目都合理就好,因此不需要再加判断。

 

    好了,上面我们写了那么多,终于可以遍历并过滤了所有4^10种方案,得到合理的结果,所以我们还差最后一步,那就是打印的显示出最终答案。所以,我有的一些了一个打印函数,把列表里的数字改为祖母选项打印出来:

#打印结果的方法
def print_result(result):
    new = []
    for each in result:
        if each == 0:
            new.append('A')
        if each == 1:
            new.append('B')
        if each == 2:
            new.append('C')
        if each == 3:
            new.append('D')
    print new    

 最后调用一下这个方法,并把结果存到final_result列表里

 

print '得到了一个结果!'
print_result(t_result)
final_result.append(t_result)

 最后可以再打印一下final_result,看看所有结果:

 

print 'final_result',final_result

 

 

Ok,大功告成,完整的程序我附在了附件里,按F5运行,就得到了打印出的结果:

 

 

      于是,借助计算机,我们费了很少的脑力解出了一份让无数人头疼的逻辑推理题。现在,我们拍着胸脯向周围的小伙伴们说:这十道题有唯一的答案A, C, B, C, A, C, D, D, B, A  了!
      

      乔布斯说过,计算机是人类思想的自行车,学会用计算机是一门很重要的技能,它可以让普通人也有能力做到天才能做的事,甚至完成的更好。所以,下次在生活中遇到令人头疼的难题时,不妨开拓一下思路,想想可不可以用计算机程序来解决,可能就会事半功倍呦!

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值