Python 求解24点

使用itertools 中相关函数求解24点游戏

排列数函数,返回列表中元素的 所有可能排列

import itertools

nums = [1, 2, 3, 4]
all_nums_list = list(itertools.permutations(nums))

for i in all_nums_list:
    print(i)


(1, 2, 3, 4)
(1, 2, 4, 3)
(1, 3, 2, 4)
(1, 3, 4, 2)
(1, 4, 2, 3)
(1, 4, 3, 2)
(2, 1, 3, 4)
(2, 1, 4, 3)
(2, 3, 1, 4)
(2, 3, 4, 1)
(2, 4, 1, 3)
(2, 4, 3, 1)
(3, 1, 2, 4)
(3, 1, 4, 2)
(3, 2, 1, 4)
(3, 2, 4, 1)
(3, 4, 1, 2)
(3, 4, 2, 1)
(4, 1, 2, 3)
(4, 1, 3, 2)
(4, 2, 1, 3)
(4, 2, 3, 1)
(4, 3, 1, 2)
(4, 3, 2, 1)

序列生成函数,返回列表元素所有可能的可重排列,即元素可使用多次

ops = ['+', '-', '*', '//']
all_ops_list = list(itertools.product(ops, repeat=3))

for i in all_ops_list:
    print(i)
('+', '+', '+')
('+', '+', '-')
('+', '+', '*')
('+', '+', '//')
('+', '-', '+')
('+', '-', '-')
('+', '-', '*')
('+', '-', '//')
('+', '*', '+')
('+', '*', '-')
('+', '*', '*')
('+', '*', '//')
('+', '//', '+')
('+', '//', '-')
('+', '//', '*')
('+', '//', '//')
('-', '+', '+')
('-', '+', '-')
('-', '+', '*')
('-', '+', '//')
('-', '-', '+')
('-', '-', '-')
('-', '-', '*')
('-', '-', '//')
('-', '*', '+')
('-', '*', '-')
('-', '*', '*')
('-', '*', '//')
('-', '//', '+')
('-', '//', '-')
('-', '//', '*')
('-', '//', '//')
('*', '+', '+')
('*', '+', '-')
('*', '+', '*')
('*', '+', '//')
('*', '-', '+')
('*', '-', '-')
('*', '-', '*')
('*', '-', '//')
('*', '*', '+')
('*', '*', '-')
('*', '*', '*')
('*', '*', '//')
('*', '//', '+')
('*', '//', '-')
('*', '//', '*')
('*', '//', '//')
('//', '+', '+')
('//', '+', '-')
('//', '+', '*')
('//', '+', '//')
('//', '-', '+')
('//', '-', '-')
('//', '-', '*')
('//', '-', '//')
('//', '*', '+')
('//', '*', '-')
('//', '*', '*')
('//', '*', '//')
('//', '//', '+')
('//', '//', '-')
('//', '//', '*')
('//', '//', '//')

首先生成传入的序列的所有可能排列,数字不可重复,为了拼接方便使用字符串表示数字

然后生成运算符的所有排列,运算符可重复

按照括号的加法,分别构造不同序列,然后使用eval函数求值,将满足要求的序列加入列表返回即可

代码

import itertools
import random


def solve24(nums):
    # nums = ['1', '2', '3', '4']

    all_nums_list = list(itertools.permutations(nums))

    ops = ['+', '-', '*', '//']
    all_ops_list = list(itertools.product(ops, repeat=3))

    # 一共有以下几种运算顺序
    # a + b + c + d
    # (a b) (c d)
    # (a (b  c) d)
    # a + (b+(c+d))
    # a + ((b+c)+d)
    # (a+(b+c)) + d

    # a + b + c + d
    all_list = [
        i[0] + j[0] + i[1] + j[1] + i[2] + j[2] + i[3]
        for i in all_nums_list
        for j in all_ops_list
    ]

    # (a b) (c d)
    all_list += [
        '(' + i[0] + j[0] + i[1] + ')' + j[1] + '(' + i[2] + j[2] + i[3] + ')'
        for i in all_nums_list
        for j in all_ops_list
    ]

    # (a+(b + c)+d)
    all_list += [
        '(' + i[0] + j[0] + '(' + i[1] + j[1] + i[2] + ')' + j[2] + i[3] + ')'
        for i in all_nums_list
        for j in all_ops_list
    ]

    # a + (b+(c+d))
    all_list += [
        i[0] + j[0] + '(' + i[1] + j[1] + '(' + i[2] + j[2] + i[3] + '))'
        for i in all_nums_list
        for j in all_ops_list
    ]

    # a + ((b+c)+d)
    all_list += [
        f"{i[0]}{j[0]}(({i[1]}{j[1]}{i[2]}){j[2]}{i[3]})"
        for i in all_nums_list
        for j in all_ops_list
    ]

    # (a+(b+c)) + d
    all_list += [
        f"({i[0]}{j[0]}({i[1]}{j[1]}{i[2]})){j[2]}{i[3]}"
        for i in all_nums_list
        for j in all_ops_list
    ]

    ans = []
    for i in all_list:
        # 可能会有除0错误
        # 1//((2//4)*3) integer division or modulo by zero
        try:
            ret = eval(i)
            if ret == 24:
                # print(i)
                ans.append(i)
        except Exception as e:
            # print(i, e)
            pass
    return ans


all_nums = [str(i) for i in range(1, 10)]
for i in range(10):
    nums = random.sample(all_nums, 4)
    print(nums)
    ret = solve24(nums)
    for j in ret:
        print(j)
 

结果的一部分

['7', '1', '8', '4']
8*4-7-1
8*4-1-7
4*8-7-1
4*8-1-7
(7-(4*1))*8
(7-(4//1))*8
(1*(7-4))*8
(8*(7-4))*1
(8*(7-4))//1


['9', '4', '5', '6']
9+4+5+6
9+4+6+5
(6*4)*(9//5)
(6*4)//(9//5)

['5', '9', '2', '4']
5*4+9//2
9//2+5*4
9//2*5+4
9//2+4*5
4*5+9//2
4+9//2*5

猜你喜欢

转载自my.oschina.net/ahaoboy/blog/1814501