首页 > 解决方案 > 如何在转换后找到两个等价的表达式(例如交换律等)

问题描述

我正在为我的表弟制作一个 24 分的游戏,我设计的程序是为给定的四个或五个数字输出所有可能的解决方案。底层机制基本上是找到所有可能的括号位置并拟合数字以查看结果是否为 24。程序现在能够找到所有答案,但存在一个大问题。

例如,给定数字

3,3,6,7,9

一个可能的答案是

3*((9+7)/6*3)

但是,该程序也会给出类似的答案

3*(9+7)/(6/3)

3*((9+7)/(6/3))

这些实际上是等价的方程式,不应被视为不同的答案。通过删除所有包含“+(”、“-(”、“)-”、“)+”和“)*”的答案,我设法消除了一些等价的答案。有什么办法可以消除所有等价的表达式?谢谢!

我在下面附上了我当前的代码。


from itertools import permutations

while True:
    numnum = input('Please choose number of cards (enter anything other than 4 and 5 to quit the program):')
    if numnum == '4':
        try:
            a = int(input("Please enter the first number:"))
            b = int(input("Please enter the second number:"))
            c = int(input("Please enter the third number:"))
            d = int(input("Please enter the fourth number:"))
        except:
            print('WARNING: Please enter a real number!')
            continue

        print('Processing...')
        my_list = [a, b, c, d]
        # Randomly arrange a list of 4 integers
        result = [c for c in permutations(my_list, 4)]

        symbols = ["+", "-", "*", "/"]

        list2 = []  # Calculate the list of 24 permutations and combinations

        flag = False

        for one, two, three, four in result:
            for s1 in symbols:
                for s2 in symbols:
                    for s3 in symbols:
                        if s1 + s2 + s3 in ['+++', '***', '+--', '++-', '**/', '*//', '///']:
                            express = ["{0}{1}{2}{3}{4}{5}{6}".format(one, s1, two, s2, three, s3, four)]
                        elif s1 + s2 + s3 in ['+-+', '-++', '-+-', '--+', '*/*', '/**', '/*/', '//*']:
                            continue
                        else:
                            express = ["({0}{1}{2}){3}{4}{5}{6}".format(one, s1, two, s2, three, s3, four),
                                       "({0}{1}{2}{3}{4}){5}{6}".format(one, s1, two, s2, three, s3, four),
                                       "{0}{1}({2}{3}{4}){5}{6}".format(one, s1, two, s2, three, s3, four),
                                       "{0}{1}({2}{3}{4}{5}{6})".format(one, s1, two, s2, three, s3, four),
                                       "{0}{1}{2}{3}({4}{5}{6})".format(one, s1, two, s2, three, s3, four),
                                       "(({0}{1}{2}){3}{4}){5}{6}".format(one, s1, two, s2, three, s3, four),
                                       "({0}{1}{2}){3}({4}{5}{6})".format(one, s1, two, s2, three, s3, four),
                                       "({0}{1}({2}{3}{4})){5}{6}".format(one, s1, two, s2, three, s3, four),
                                       "{0}{1}(({2}{3}{4}){5}{6})".format(one, s1, two, s2, three, s3, four),
                                       "{0}{1}({2}{3}({4}{5}{6}))".format(one, s1, two, s2, three, s3, four)]

                        for e in express:
                            try:
                                if eval(e) == 24:
                                    list2.append(e)
                                    flag = True
                            except ZeroDivisionError:
                                pass

        for c in list2:
            if '+(' in c or '-(' in c or ')-' in c or ')+' in c or ')*' in c:
                continue
            print(c)

        if not flag:
            print("NO solution...")

    elif numnum == '5':
        try:
            a = int(input("Please enter the first number:"))
            b = int(input("Please enter the second number:"))
            c = int(input("Please enter the third number:"))
            d = int(input("Please enter the fourth number:"))
            e = int(input('Please enter the fifth number:'))
        except:
            print('WARNING: Please enter a real number!')
            continue

        print('Processing...')
        my_list = [a, b, c, d, e]
        # Randomly arrange a list of 4 integers
        result = [c for c in permutations(my_list, 5)]

        symbols = ["+", "-", "*", "/"]

        list2 = []  # Calculate the list of 24 permutations and combinations

        flag = False

        for one, two, three, four, five in result:
            for s1 in symbols:
                for s2 in symbols:
                    for s3 in symbols:
                        for s4 in symbols:
                            if s1 + s2 + s3 + s4 in ['++++', '****', '+---', '+++-', '++--', '**//', '*///', '///',
                                                     '***/']:
                                express = ["{0}{1}{2}{3}{4}{5}{6}{7}{8}".format(one, s1, two, s2, three, s3, four, s4, five)]
                            elif (s1, s2, s3, s4) in permutations(['*', '/', '/', '/']) \
                                    or (s1, s2, s3, s4) in permutations(['*', '*', '/', '/']) \
                                    or (s1, s2, s3, s4) in permutations(['*', '*', '*', '/']) \
                                    or (s1, s2, s3, s4) in permutations(['+', '-', '-', '-']) \
                                    or (s1, s2, s3, s4) in permutations(['+', '+', '-', '-']) \
                                    or (s1, s2, s3, s4) in permutations(['+', '+', '+', '-']):
                                continue
                            else:
                                express = ["({0}{1}{2}){3}{4}{5}{6}{7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "({0}{1}{2}{3}{4}){5}{6}{7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "({0}{1}{2}{3}{4}{5}{6}){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "{0}{1}({2}{3}{4}){5}{6}{7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "{0}{1}({2}{3}{4}{5}{6}){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "{0}{1}({2}{3}{4}{5}{6}{7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "{0}{1}{2}{3}({4}{5}{6}){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "{0}{1}{2}{3}({4}{5}{6}{7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "{0}{1}{2}{3}{4}{5}({6}{7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "(({0}{1}{2}){3}{4}){5}{6}{7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "(({0}{1}{2}){3}{4}{5}{6}){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "({0}{1}{2}){3}({4}{5}{6}){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "({0}{1}{2}){3}({4}{5}{6}{7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "({0}{1}{2}){3}{4}{5}({6}{7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "({0}{1}{2}{3}{4}){5}({6}{7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "(({0}{1}{2}{3}{4}){5}{6}){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "({0}{1}({2}{3}{4})){5}{6}{7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "({0}{1}({2}{3}{4}){5}{6}){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "({0}{1}{2}{3}({4}{5}{6})){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "({0}{1}({2}{3}{4}{5}{6})){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "{0}{1}(({2}{3}{4}){5}{6}){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "{0}{1}(({2}{3}{4}){5}{6}{7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "{0}{1}({2}{3}{4}){5}({6}{7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "{0}{1}({2}{3}({4}{5}{6})){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "{0}{1}(({2}{3}{4}{5}{6}){7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "{0}{1}({2}{3}({4}{5}{6}){7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "{0}{1}({2}{3}({4}{5}{6}{7}{8}))".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "{0}{1}({2}{3}{4}{5}({6}{7}{8}))".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "{0}{1}{2}{3}(({4}{5}{6}){7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "{0}{1}{2}{3}({4}{5}({6}{7}{8}))".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "((({0}{1}{2}){3}{4}){5}{6}){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "(({0}{1}{2}){3}({4}{5}{6})){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "({0}{1}{2}){3}(({4}{5}{6}){7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "({0}{1}{2}){3}({4}{5}({6}{7}{8}))".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "(({0}{1}({2}{3}{4})){5}{6}){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "({0}{1}({2}{3}{4})){5}({6}{7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "({0}{1}(({2}{3}{4}){5}{6})){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "({0}{1}({2}{3}({4}{5}{6}))){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "{0}{1}((({2}{3}{4}){5}{6}){7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "{0}{1}(({2}{3}{4}){5}({6}{7}{8}))".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "{0}{1}(({2}{3}({4}{5}{6})){7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "{0}{1}({2}{3}(({4}{5}{6}){7}{8}))".format(one, s1, two, s2, three, s3, four, s4, five),
                                           "{0}{1}({2}{3}({4}{5}({6}{7}{8})))".format(one, s1, two, s2, three, s3, four, s4, five)]

                            for e in express:
                                try:
                                    if eval(e) == 24:
                                        list2.append(e)
                                        flag = True
                                except ZeroDivisionError:
                                    pass

        for c in list2:
            if '+(' in c or '-(' in c or ')-' in c or ')+' in c or ')*' in c:
                continue
            print(c)

        if not flag:
            print("NO solution...")
    else:
        break

标签: pythonmathoperatorssympy

解决方案


你试过使用eval()吗?

for i, e1 in sorted(enumerate(express), reverse=True): # reversed and enumerate so we can remove during iteration by popping an index
    for n, e2 in sorted(enumerate(express), reverse=True):
        if e1 != e2: # checks that it isn't comparing against itself as a string
            if eval(e1) == eval(e2):
                express.pop(n)

eval()可预测地评估字符串文字中任何表达式的值。添加上面的内容应该检查express列表中的每个表达式,并将其与其他所有表达式进行检查。

关于使用反向枚举列表:这是一种允许您在列表迭代期间从列表中删除元素的方法。enumerate()在 ing 之前,它会为您提供原始列表中项目的索引sorted(reverse=True)。您将其反转,以便如果从原始列表中删除一个项目,则它之前的所有项目的索引都不会受到影响。

编辑:澄清和标记


推荐阅读