问题:
据说是爱因斯坦在20世纪初出的这个谜语
1. 在一条街上,有5座房子,喷了5种颜色。 2. 每个房里住着不同国籍的人。 3. 每个人喝不同的饮料,抽不同品牌的香烟,养不同的宠物。 问题是:谁养鱼?
提示:
1. 英国人住红色房子。
2. 瑞典人养狗。
3. 丹麦人喝茶。
4. 绿色房子在白色房子左面。
5. 绿色房子主人喝咖啡。
6. 抽Pall Mall 香烟的人养鸟。
7. 黄色房子的主人抽Dunhill香烟。
8. 住在中间房子的人喝牛奶。
9. 挪威人住第一间房。
10. 抽Blends香烟的人住在养猫的人的隔壁。
11. 养马的人住抽Dunhill香烟的人的隔壁。
12. 抽Blue Master 的人喝啤酒。
13. 德国人抽Prince香烟。
14. 挪威人住蓝色房子隔壁。
15. 抽Blends香烟的人有一个喝水的邻居
思路:
思路其实很粗暴,直接列举出所有的情况,然后用15个提示验证,如果15个条件完全符合就找到答案。
- 房子共有颜色5种颜色,五种颜色的全排列是120种可能
- 加上 房子里住的人国籍不同,饮料不同,宠物不同,抽烟不同每种都有120种可能
- 所以共有种可能,就是14883200000种情况,简单点就是248亿种可能,所有不优化直接跑会很慢。
1.这是第一次运行的程序,
直接用python跑的,我的机器是配置是windows系统 i7的cpu
import itertools
from concurrent.futures import ThreadPoolExecutor, wait
import time
def handle(data):
colour_inf = list(data[0])
pet_inf = list(data[1])
smoke_inf = list(data[2])
drinks_inf = list(data[3])
nationality_inf = list(data[4])
# 8、住在中间房子的人喝牛奶
if 'milk' != drinks_inf[2]:
return -8
# 9、 挪威人住第一间房
if 'norway' != nationality_inf[0]:
return -9
# 1、英国人住红色房子
index = colour_inf.index('red')
if 'britain' != nationality_inf[index]:
return -1
# 2、瑞典人养狗
index = pet_inf.index('dog')
if 'sweden' != nationality_inf[index]:
return -2
# 3、丹麦人喝茶
index = drinks_inf.index('tea')
if 'denmark' != nationality_inf[index]:
return -3
###################################################
# 4、绿色房子在白色房子左面
index = colour_inf.index('green')
if 4 == index: # 绿色房子在最后
return -4
if 'white' != colour_inf[index + 1]:
return -4
# 5、绿色房子主人喝咖啡
if 'coffee' != drinks_inf[index]:
return -5
####################################################
# 6、抽Pall Mall 香烟的人养鸟
index = smoke_inf.index('pallmall')
if 'bird' != pet_inf[index]:
return -6
# 7、黄色房子主人抽Dunhill 香烟
index = smoke_inf.index('dunhill')
if 'yellow' != colour_inf[index]:
return -7
# 10、抽Blends香烟的人住在养猫的人隔壁
index = smoke_inf.index('blends')
cat_index = pet_inf.index('cat')
if 1 != cat_index - index and -1 != cat_index - index:
return -10
# 11、养马的人住抽Dunhill 香烟的人隔壁
index = smoke_inf.index('dunhill')
horse_index = pet_inf.index('horse')
if 1 != horse_index - index and -1 != horse_index - index:
return -11
# 12、抽Blue Master的人喝啤酒
index = smoke_inf.index('bluemaster')
if 'beer' != drinks_inf[index]:
return -12
# 13、德国人抽Prince香烟
index = smoke_inf.index('prince')
if 'germany' != nationality_inf[index]:
return -13
# 14、挪威人住蓝色房子隔壁 ----(以结合信息9判断,第二间房子为蓝色)
if 'blue' != colour_inf[1]:
return -14
# 15、抽Blends香烟的人有一个喝水的邻居
index = smoke_inf.index('blends')
water_index = drinks_inf.index('water')
if 1 != water_index - index and -1 != water_index - index:
return -15
print('找到答案')
print(data)
exit()
if __name__ == "__main__":
colour_list = list(itertools.permutations(['red', 'yellow', 'blue', 'white', 'green'], 5))
pet_list = list(itertools.permutations(['cat', 'horse', 'fish', 'bird', 'dog'], 5))
smoke_list = list(itertools.permutations(['pallmall', 'dunhill', 'bluemaster', 'blends', 'prince'], 5))
drinks_list = list(itertools.permutations(['tea', 'water', 'coffee', 'beer', 'milk'], 5))
nationality_list = list(itertools.permutations(['britain', 'denmark', 'norway', 'germany', 'sweden'], 5))
num = 0
for colour in colour_list:
for pet in pet_list:
for smoke in smoke_list:
start = time.time()
for drinks in drinks_list:
for nationality in nationality_list:
data_list = [colour, pet, smoke, drinks, nationality]
handle(data_list)
num += 1
end = time.time()
print("完成%d次计算用时:%0.4f, 完成进度%0.10f" % (num * 14400, end - start, num * 14400 / 24883200000))
这是结果,速度特别慢,跑了可能半晚上吧,因为自己计算时间的代码没写好,具体时间也不知到。
"""
完成6432004800次计算用时:0.0200, 完成进度0.2584878472
完成6432019200次计算用时:0.0200, 完成进度0.2584884259
完成6432033600次计算用时:0.0200, 完成进度0.2584890046
完成6432048000次计算用时:0.0200, 完成进度0.2584895833
完成6432062400次计算用时:0.0200, 完成进度0.2584901620
完成6432076800次计算用时:0.0200, 完成进度0.2584907407
完成6432091200次计算用时:0.0200, 完成进度0.2584913194
完成6432105600次计算用时:0.0200, 完成进度0.2584918981
完成6432120000次计算用时:0.0200, 完成进度0.2584924769
完成6432134400次计算用时:0.0200, 完成进度0.2584930556
完成6432148800次计算用时:0.0200, 完成进度0.2584936343
找到答案
[('yellow', 'blue', 'red', 'green', 'white'),
('cat', 'horse', 'bird', 'fish', 'dog'),
('dunhill', 'blends', 'pallmall', 'prince', 'bluemaster'),
('water', 'tea', 'milk', 'coffee', 'beer'),
('norway', 'denmark', 'britain', 'germany', 'sweden')]
Process finished with exit code 0
"""
2.第二次
第二次用pypy跑的程序,而且把元组转字典的操作放到了循环之外进行,跑到大概所有情况的25%就找到了答案,用时两分钟左右,
import itertools
from concurrent.futures import ThreadPoolExecutor, wait
import time
def handle(data):
# 8、住在中间房子的人喝牛奶
if 'milk' != data[3][2]:
return -8
# 9、 挪威人住第一间房
if 'norway' != data[4][0]:
return -9
# 14、挪威人住蓝色房子隔壁 ----(以结合信息9判断,第二间房子为蓝色)
if 'blue' != data[0][1]:
return -14
# 1、英国人住红色房子
index = data[0].index('red')
if 'britain' != data[4][index]:
return -1
# 2、瑞典人养狗
index = data[1].index('dog')
if 'sweden' != data[4][index]:
return -2
# 3、丹麦人喝茶
index = data[3].index('tea')
if 'denmark' != data[4][index]:
return -3
# 6、抽Pall Mall 香烟的人养鸟
index = data[2].index('pallmall')
if 'bird' != data[1][index]:
return -6
# 7、黄色房子主人抽Dunhill 香烟
index = data[2].index('dunhill')
if 'yellow' != data[0][index]:
return -7
# 12、抽Blue Master的人喝啤酒
index = data[2].index('bluemaster')
if 'beer' != data[3][index]:
return -12
# 13、德国人抽Prince香烟
index = data[2].index('prince')
if 'germany' != data[4][index]:
return -13
###################################################
# 4、绿色房子在白色房子左面
index = data[0].index('green')
if 4 == index: # 绿色房子在最后
return -4
if 'white' != data[0][index + 1]:
return -4
# 5、绿色房子主人喝咖啡
if 'coffee' != data[3][index]:
return -5
####################################################
# 10、抽Blends香烟的人住在养猫的人隔壁
index = data[2].index('blends')
cat_index = data[1].index('cat')
if 1 != cat_index - index and -1 != cat_index - index:
return -10
# 11、养马的人住抽Dunhill 香烟的人隔壁
index = data[2].index('dunhill')
horse_index = data[1].index('horse')
if 1 != horse_index - index and -1 != horse_index - index:
return -11
# 15、抽Blends香烟的人有一个喝水的邻居
index = data[2].index('blends')
water_index = data[3].index('water')
if 1 != water_index - index and -1 != water_index - index:
return -15
print('找到答案')
print(data)
return 0
# exit()
if __name__ == "__main__":
colour_list = list(itertools.permutations(['red', 'yellow', 'blue', 'white', 'green'], 5))
pet_list = list(itertools.permutations(['cat', 'horse', 'fish', 'bird', 'dog'], 5))
smoke_list = list(itertools.permutations(['pallmall', 'dunhill', 'bluemaster', 'blends', 'prince'], 5))
drinks_list = list(itertools.permutations(['tea', 'water', 'coffee', 'beer', 'milk'], 5))
nationality_list = list(itertools.permutations(['britain', 'denmark', 'norway', 'germany', 'sweden'], 5))
for i in range(120):
colour_list[i] = list(colour_list[i])
for i in range(120):
pet_list[i] = list(pet_list[i])
for i in range(120):
smoke_list[i] = list(smoke_list[i])
for i in range(120):
drinks_list[i] = list(drinks_list[i])
for i in range(120):
nationality_list[i] = list(nationality_list[i])
num = 0
start = time.time()
for colour in colour_list:
for pet in pet_list:
for smoke in smoke_list:
for drinks in drinks_list:
for nationality in nationality_list:
data_list = [colour, pet, smoke, drinks, nationality]
if 0 == handle(data_list):
exit()
num += 1
end = time.time()
print("完成%d次计算用时:%0.4f秒, 完成进度%0.10f" % (num * 1728000, end - start, num * 1728000 / 24883200000))
"""
这是程序运行结果
完成6431616000次计算用时:113.8808秒, 完成进度0.2584722222
找到答案
[['yellow', 'blue', 'red', 'green', 'white'],
['cat', 'horse', 'bird', 'fish', 'dog'],
['dunhill', 'blends', 'pallmall', 'prince', 'bluemaster'],
['water', 'tea', 'milk', 'coffee', 'beer'],
['norway', 'denmark', 'britain', 'germany', 'sweden']]
Process finished with exit code 0
"""
3.第三次
这一次还是使用pypy来跑,主要的优化在根据提示在循环外条件删除掉一些情况,比如根据提示8(住在中间房子的人喝牛奶),排除所有牛奶不在中间的情况,
最终时间到了1-2秒可以出结果
具体修改如下
# for i in range(120):
# colour_list[i] = list(colour_list[i])
for colour in colour_list_:
colour = list(colour)
if "blue" == colour[1]:
colour_list.append(colour)
# for i in range(120):
# nationality_list[i] = list(nationality_list[i])
for nationality in nationality_list_:
nationality = list(nationality)
if 'norway' == nationality[0]:
nationality_list.append(nationality)
# for i in range(120):
# drinks_list[i] = list(drinks_list[i])
for drinks in drinks_list_:
drinks = list(drinks)
if 'milk' == drinks[2]:
drinks_list.append(drinks)
for i in range(120):
pet_list.append(list(pet_list_[i]))
for i in range(120):
smoke_list.append(list(smoke_list_[i]))
全部代码如下:
import itertools
from concurrent.futures import ThreadPoolExecutor, wait
import time
def handle(data):
# # 8、住在中间房子的人喝牛奶
# if 'milk' != data[3][2]:
# return -8
#
# # 9、 挪威人住第一间房
# if 'norway' != data[4][0]:
# return -9
#
# # 14、挪威人住蓝色房子隔壁 ----(以结合信息9判断,第二间房子为蓝色)
# if 'blue' != data[0][1]:
# return -14
# 1、英国人住红色房子
index = data[0].index('red')
if 'britain' != data[4][index]:
return -1
# 2、瑞典人养狗
index = data[1].index('dog')
if 'sweden' != data[4][index]:
return -2
# 3、丹麦人喝茶
index = data[3].index('tea')
if 'denmark' != data[4][index]:
return -3
# 6、抽Pall Mall 香烟的人养鸟
index = data[2].index('pallmall')
if 'bird' != data[1][index]:
return -6
# 7、黄色房子主人抽Dunhill 香烟
index = data[2].index('dunhill')
if 'yellow' != data[0][index]:
return -7
# 12、抽Blue Master的人喝啤酒
index = data[2].index('bluemaster')
if 'beer' != data[3][index]:
return -12
# 13、德国人抽Prince香烟
index = data[2].index('prince')
if 'germany' != data[4][index]:
return -13
###################################################
# 4、绿色房子在白色房子左面
index = data[0].index('green')
if 4 == index: # 绿色房子在最后
return -4
if 'white' != data[0][index + 1]:
return -4
# 5、绿色房子主人喝咖啡
if 'coffee' != data[3][index]:
return -5
####################################################
# 10、抽Blends香烟的人住在养猫的人隔壁
index = data[2].index('blends')
cat_index = data[1].index('cat')
if 1 != cat_index - index and -1 != cat_index - index:
return -10
# 11、养马的人住抽Dunhill 香烟的人隔壁
index = data[2].index('dunhill')
horse_index = data[1].index('horse')
if 1 != horse_index - index and -1 != horse_index - index:
return -11
# 15、抽Blends香烟的人有一个喝水的邻居
index = data[2].index('blends')
water_index = data[3].index('water')
if 1 != water_index - index and -1 != water_index - index:
return -15
print('找到答案')
for dd in data:
print(dd)
return 0
# exit()
if __name__ == "__main__":
colour_list_ = list(itertools.permutations(['red', 'yellow', 'blue', 'white', 'green'], 5))
pet_list_ = list(itertools.permutations(['cat', 'horse', 'fish', 'bird', 'dog'], 5))
smoke_list_ = list(itertools.permutations(['pallmall', 'dunhill', 'bluemaster', 'blends', 'prince'], 5))
drinks_list_ = list(itertools.permutations(['tea', 'water', 'coffee', 'beer', 'milk'], 5))
nationality_list_ = list(itertools.permutations(['britain', 'denmark', 'norway', 'germany', 'sweden'], 5))
colour_list = []
pet_list = []
smoke_list = []
drinks_list = []
nationality_list = []
# for i in range(120):
# colour_list[i] = list(colour_list[i])
for colour in colour_list_:
colour = list(colour)
if "blue" == colour[1]:
colour_list.append(colour)
# for i in range(120):
# nationality_list[i] = list(nationality_list[i])
for nationality in nationality_list_:
nationality = list(nationality)
if 'norway' == nationality[0]:
nationality_list.append(nationality)
# for i in range(120):
# drinks_list[i] = list(drinks_list[i])
for drinks in drinks_list_:
drinks = list(drinks)
if 'milk' == drinks[2]:
drinks_list.append(drinks)
for i in range(120):
pet_list.append(list(pet_list_[i]))
for i in range(120):
smoke_list.append(list(smoke_list_[i]))
num = 0
start = time.time()
for colour in colour_list:
for pet in pet_list:
for smoke in smoke_list:
for drinks in drinks_list:
for nationality in nationality_list:
data_list = [colour, pet, smoke, drinks, nationality]
num += 1
if 0 == handle(data_list):
print("总的运行次数 %d" % num)
exit()
end = time.time()
print("计算用时:%0.4f秒" % (end - start))
"""
结果
计算用时:1.8623秒
找到答案
['yellow', 'blue', 'red', 'green', 'white']
['cat', 'horse', 'bird', 'fish', 'dog']
['dunhill', 'blends', 'pallmall', 'prince', 'bluemaster']
['water', 'tea', 'milk', 'coffee', 'beer']
['norway', 'denmark', 'britain', 'germany', 'sweden']
总的运行次数 58220503
Process finished with exit code 0
Process finished with exit code 0
Process finished with exit code 0
"""