鱼C论坛

 找回密码
 立即注册
查看: 5168|回复: 11

如何有python求解爱因斯坦五个屋子题

[复制链接]
发表于 2016-1-25 20:09:34 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
这个问题传言出自爱因斯坦。感觉比较有趣,所以想试着用python求解试试
有一排五间房子,每一间房子的颜色都不同。在这些房子里住着五个不同国籍的人。每个人喂养了不同的动物,喜欢不同的饮料,抽不同的雪茄。
英国人住在红色房子里。
瑞典人养狗。
丹麦人喝茶。
绿色的房子在白色房子的左边。
绿色房子的主人喜欢喝咖啡。
抽“坡魔”牌雪茄的人养鸟。
黄色房子的主人抽“顿山”牌雪茄。
住在中间房子的人喝牛奶。
挪威人住在第一间房子。
抽“波兰斯”牌雪茄的人住在养猫的人旁边。
养马的人住在抽“顿山”牌雪茄的人旁边。
抽“蓝领”牌雪茄的人喝啤酒。
德国人抽“王子”牌雪茄。
挪威人住在蓝色房子旁边。
抽“波兰斯”牌雪茄的人有一个喝水的邻居。
谁家养鱼?

具体要求:1.给出最终的结果已经各个屋子的信息。2,.能否用python给出具体的推理过程。。。。
这题开放性比较大,枚举法应该是个比较容易想到的方法。。具体结果大家有兴趣的集思广益下哈!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2016-1-25 20:29:01 | 显示全部楼层
数据结构
@冬雪雪冬 @小甲鱼
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-1-26 01:44:24 | 显示全部楼层
hldh214 发表于 2016-1-25 20:29
数据结构
@冬雪雪冬 @小甲鱼

为啥他们总喜欢把智力游戏的题目用 Python 来解?难道木有题目可以出了吗??
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2016-1-26 08:32:33 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-1-26 11:15:32 | 显示全部楼层
1号房子     2号房子     3号房子     4号房子     5号房子
Norway    Denmark   English     Germany   Sweden
Yellow      Blue           Red          Green        White
Cat           Horse         Bird          Fish           Dog
Water       Tea             Milk         Coffee       Beer
顿山          波兰斯         坡魔         王子           蓝领



4号房子的德国人养鱼
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-1-26 16:20:59 | 显示全部楼层
John_farmer 发表于 2016-1-26 11:15
1号房子     2号房子     3号房子     4号房子     5号房子
Norway    Denmark   English     Germany   S ...

哈哈。是编程算的么
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-1-26 16:41:35 | 显示全部楼层
65230215 发表于 2016-1-26 16:20
哈哈。是编程算的么

编程不会
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-1-26 16:45:54 | 显示全部楼层
小甲鱼 发表于 2016-1-26 01:44
为啥他们总喜欢把智力游戏的题目用 Python 来解?难道木有题目可以出了吗??

这不是人脑力不够么。。就想试试电脑力来解决。。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-1-27 11:07:54 | 显示全部楼层
65230215 发表于 2016-1-26 16:45
这不是人脑力不够么。。就想试试电脑力来解决。。

其实你用编程的方法解决这个问题所用的时间觉得是人脑直接解答所用时间段额100倍甚至1000倍,甚至如何编程能力不天才,智商捉急的话,这辈子别想解决!!!
还是老老实实用纸笔解决吧,少年!!!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-1-28 00:02:28 | 显示全部楼层
John_farmer 发表于 2016-1-27 11:07
其实你用编程的方法解决这个问题所用的时间觉得是人脑直接解答所用时间段额100倍甚至1000倍,甚至如何编 ...

其实纸笔早就解决了。。。只是好奇编程如何实现。哈哈
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-1-28 00:05:09 | 显示全部楼层
自问自答。贴代码。不过很奇怪,运行起来很快就出结果。照理说应该枚举一会儿。。不知道哪儿出了问题。下面贴代码。。
  1. # 分段测试test1、2、3可以提高代码运行效率。   
  2. # 学习了如何用local()设置动态变量名,但并未用到。
  3. # 如何实现多层循环嵌套并退出循环。。
  4. # 提前提取题意中的直接信息来简化枚举数据的量
  5. #用itertools库来穷尽列表的枚举结果。
  6. import itertools
  7. import time
  8. import random
  9. i = 0
  10. def test1(A):
  11.     i = A[0].index('red')  # 红色房子的id
  12.     i0 = A[4].index('dog')  # 养狗的id
  13.     i1 = A[1].index('tea')  # 茶的id
  14.     i2 = A[0].index('green')  # 绿色房子id
  15.     i10 = A[0].index('white')  # 黄色房子
  16.     if A[3][0] != 'Norway':
  17.         print(A[3][0])
  18.         #  print('最前面住的不是挪威')
  19.         return 1
  20.     elif A[3][i] != 'UK':
  21.         # print(A[3][i])
  22.         #   print('英国人不住在红色房子里。')
  23.         return 2
  24.     elif A[3][i0] != 'Sweden':
  25.         # print('瑞典人不养狗。')
  26.         return 3
  27.     elif A[3][i1] != 'Denmark':
  28.         #  print('丹麦人不喝茶。')
  29.         return 4
  30.     elif i2 + 1 != i10:
  31.         # print('绿色的房子不在白色房子的左边。')
  32.         return 5
  33.     elif A[1][i2] != 'coffee':
  34.         # print('绿色房子的主人不喜欢喝咖啡。')
  35.         return 6
  36.     else:
  37.         return 0
  38. def test2(A):
  39.     i3 = A[0].index('yellow')  # 黄色房子
  40.     i4 = A[2].index('坡魔')
  41.     if A[4][i4] != 'bird':
  42.         # print('抽“坡魔”牌雪茄的人不养鸟。')
  43.         return 7
  44.     elif A[2][i3] != '顿山':
  45.         # print('黄色房子的主人不抽“顿山”牌雪茄。')
  46.         return 8
  47.     elif A[1][2] != 'milk':
  48.         #  print('谁谁不喝牛奶')
  49.         return 9
  50.     else:
  51.         return 0
  52. def test3(A):
  53.     i5 = A[4].index('cat')  # 养猫的人id
  54.     i6 = A[4].index('horse')  # 养马的人id
  55.     i7 = A[1].index('beer')  # 喝啤酒id
  56.     i8 = A[3].index('Germany')  # 德国人id
  57.     i9 = A[1].index('water')
  58.     if i5 == 0 and A[2][i5 + 1] != '波兰斯':
  59.         #   print('抽“波兰斯”牌雪茄的人不住在养猫的人旁边。')
  60.         return 11
  61.     if i5 == 4 and A[2][i5 - 1] != '波兰斯':
  62.         return 12
  63.     elif i5 % 4 != 0 and A[2][i5 + 1] != '波兰斯' and A[2][i5 - 1] != '波兰斯':
  64.         #  print('抽“波兰斯”牌雪茄的人不住在养猫的人旁边。')
  65.         return 12
  66.     elif i6 == 0 and A[2][i6 + 1] != '顿山':
  67.         #  print('养马的人不住在抽“顿山”牌雪茄的人旁边。')
  68.         return 13
  69.     elif i6 == 4 and A[2][i6 - 1] != '顿山':
  70.         return 14
  71.     elif i6 % 4 != 0 and A[2][i6 + 1] != '顿山' and A[2][i6 - 1] != '顿山':
  72.         # print('养马的人不住在抽“顿山”牌雪茄的人旁边。')
  73.         return 15
  74.     elif A[2][i7] != '蓝领':
  75.         # print('抽“蓝领”牌雪茄的人不喝啤酒。')
  76.         return 16
  77.     elif A[2][i8] != '王子':
  78.         # print('德国人不抽“王子”牌雪茄。')
  79.         return 17
  80.     elif A[0][1] != 'blue':
  81.         # print('挪威人住在蓝色房子旁边。')
  82.         return 18
  83.     elif i9 == 0 and A[2][i9 + 1] != '波兰斯':
  84.         # print('抽“波兰斯”牌雪茄的人有一个喝水的邻居。')
  85.         return 19
  86.     elif i9 == 4 and A[2][i9 - 1] != '波兰斯':
  87.         # print('抽“波兰斯”牌雪茄的人有一个喝水的邻居。')
  88.         return 20
  89.     elif i9 % 4 != 0 and A[2][i9 + 1] != '波兰斯' and A[2][i9 - 1] != '波兰斯':
  90.         #  print('抽“波兰斯”牌雪茄的人有一个喝水的邻居。')
  91.         return 21
  92.     else:
  93.         return 0
  94. colour = ['red', 'yellow', 'green', 'white']
  95. random.shuffle(colour)
  96. iter1 = list(itertools.permutations(colour))
  97. drink = ['water', 'tea', 'coffee', 'beer']
  98. random.shuffle(drink)
  99. iter2 = list(itertools.permutations(drink))
  100. smoke = ['蓝领', '坡魔', '波兰斯', '王子', '顿山']
  101. random.shuffle(smoke)
  102. iter3 = list(itertools.permutations(smoke))
  103. country = ['Denmark', 'Sweden', 'UK', 'Germany']
  104. random.shuffle(country)
  105. print(country)
  106. iter4 = list(itertools.permutations(country))
  107. pet = ['horse', 'bird', 'cat', 'fish', 'dog']
  108. random.shuffle(pet)
  109. print(drink, smoke, pet, country, colour)
  110. iter5 = list(itertools.permutations(pet))
  111. i = 0


  112. def main():
  113.     for j1 in iter1:
  114.         for j2 in iter2:
  115.             for j3 in iter3:
  116.                 for j4 in iter4:
  117.                     for j5 in iter5:
  118.                         global i
  119.                         i += 1
  120.                         print(i)
  121.                         if i % 1000000 == 0 and i <= 20000000:
  122.                             print('已检查%d种组合.' % i)
  123.                         if i % 1000000 == 0 and 20000000 < i <= 40000000:
  124.                             print('已检查%d种组合。你可能运气不佳。平均需要检查1亿种组合,请等待~' % i)
  125.                         if i % 1000000 == 0 and 40000000 < i <= 80000000:
  126.                             print('已检查%d种组合。坚持,胜利就在眼前~' % i)
  127.                         if i % 1000000 == 0 and 80000000 < i <= 160000000:
  128.                             print('已检查%d种组合。我已经看到前方的答案了~' % i)

  129.                         j22 = list(j2)  # 元祖必须转换为list才能进行insert操作。
  130.                         j22.insert(2, 'milk')
  131.                         j11 = list(j1)
  132.                         j11.insert(1, 'blue')
  133.                         j44 = list(j4)
  134.                         j44.insert(0, 'Norway')
  135.                         A = [j11, j22, j3, j44, j5]
  136.                         if test1(A) == 0:
  137.                             if test2(A) == 0:
  138.                                 if test3(A) == 0:
  139.                                     break
  140.                                 break
  141.                             break
  142.                         break
  143.                     return A, i


  144. starttime = time.time()
  145. main()
  146. endtime = time.time()
  147. print('共测试了%d个样本,用时%d秒。' % ((main()[1]), endtime - starttime))
  148. result = main()[0]
  149. for i in range(1, 6):
  150.     info = result
  151.     print('第%d个房子是%s的,主人是%s人,爱喝%s,爱抽%s烟,养%s。' % (
  152.         i, info[0][i - 1], info[3][i - 1], info[1][i - 1], info[2][i - 1], info[4][i - 1]))
  153. print('OK,这样一道之前和刁一块儿思考的爱因斯坦五房子题终于用编程的办法解出来啦!不过过程慢哈。anyway,祝生日快乐,学业有成!')
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-1-28 08:41:07 | 显示全部楼层
65230215 发表于 2016-1-28 00:05
自问自答。贴代码。不过很奇怪,运行起来很快就出结果。照理说应该枚举一会儿。。不知道哪儿出了问题。下面 ...

屌屌屌
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2026-2-19 09:23

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表