Python求解爱因斯坦的鱼

本文介绍了如何使用Python逐步优化解决爱因斯坦著名的谜题,从原始的全排列搜索导致的效率低下,到通过PYPY和提前删除无效情况的优化,最后利用多线程进一步提升速度,达到秒级解决方案。
摘要由CSDN通过智能技术生成

问题:

据说是爱因斯坦在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个条件完全符合就找到答案。

  1. 房子共有颜色5种颜色,五种颜色的全排列是120种可能
  2. 加上 房子里住的人国籍不同,饮料不同,宠物不同,抽烟不同每种都有120种可能
  3. 所以共有120^{5}种可能,就是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()

                    f
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值