Python求解爱因斯坦的鱼

问题:

据说是爱因斯坦在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()

                    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
"""

猜你喜欢

转载自blog.csdn.net/qq_31232793/article/details/82253863