繁体   English   中英

使用随机数列表和所有简单的数学运算符来计算所有可能的组合,以达到给定的目标

[英]Calculating all possible combinations using a list of random numbers and ALL simple math operators to reach a given target

我正在编写一个简单的Python脚本,该脚本随机生成6个数字(从1到100)和一个较大的数字(从100到1000)。 我对该脚本的目标是:

  1. 使用至少2个数字和任何简单的数学运算(加,减,乘和除)来计算所有可能的组合

  2. 将总数大于或小于10的组合中的所有组合输出为“匹配项”

号码列表不必穷尽,但是不接受重复号码。 另外,我不太在乎代码是否有效(如果有人决定发布任何东西,我可以在任何人需要的情况下到目前为止发布我的东西,最好是在Python中发布); 只要有效,我很乐意对其进行优化。

我本人尝试过此操作,但由于程序由于运行时错误而快速结束,因此失败了。 我还尝试过在x通过之后放置一个计数器来停止循环(其中x是一个小数字,例如50),但这会使情况变得更糟,因为它会不断地继续前进。

我也进行了一些研究,发现( 从一组数字中计算目标数字 -第二个答案)是我发现的最能满足我的要求,但还没有达到要求的数字。

谢谢您的帮助! :-)

编辑:这是我的代码:

import random, time, operator

i = 0
numlist = []
while i != 6:
    number = random.randint(1, 100)
    numlist.append(number)
    i += 1

largenumber = random.randint(100, 1000)
print(numlist)
print(largenumber)

def operationTesting():
    a, c, m, total = 0, 0, 0, 0
    totalnums = 0
    operators = ['+', '-', '*', '/']
    while total != largenumber:
        for a in numlist[m]:
            for c in numlist[m+1]:
                print(a)
                print(c)
                if a == c:
                    operationTesting()
                else:
                    b = random.choice(operators)
                    if b == '+':
                        summednums = operator.add(int(a), int(c))
                        print(summednums)
                        totalnums = totalnums + summednums
                    elif b == '-':
                        summednums = operator.sub(int(a), int(c))
                        print(summednums)
                        totalnums = totalnums + summednums
                    elif b == '*':
                        summednums = operator.mul(int(a), int(c))
                        print(summednums)
                        totalnums = totalnums + summednums
                    elif b == '/':
                        summednums = operator.floordiv(int(a), int(c))
                        print(summednums)
                        totalnums = totalnums + summednums
                    print(totalnums)
                    SystemExit(None)

operationTesting()

一种非常整齐的方法是使用反向波兰符号或后缀符号。 这种表示法避免了使用带运算符优先级的常规算术运算时可能需要的括号。

如果您不太担心时间效率,则可以使用蛮力执行此操作。 您还需要考虑对除法的处理-如果两个数字没有精确除法,您是否要以某种方式将结果返回为“无效”(我猜是这样),还是真的要进行底数除法? 请注意,后者可能会给您一些无效的答案...

考虑numlist = [1,2,3,4,5,6]numlist = [1,2,3,4,5,6] 在RPN中,我们可以做这样的事情

RPN           Equivalent to
123456+++++   (1+(2+(3+(4+(5+6)))))
123456++++-   (1-(2+(3+(4+(5+6)))))
123456+++-+   (1+(2-(3+(4+(5+6)))))
...
12345+6+-++   (1+(2+(3-((4+5)+6))))
12345+6-+++   (1+(2+(3+((4+5)-6))))
...

等等。 您可能会看到,有了足够的组合,就可以得到数字,运算符和方括号的任何组合。 括号很重要-显然只能取3个数字

1+2*6 

通常被解释

(1 + (2*6)) == 13

并且与

((1+2)*6) == 18

在RPN中,它们分别为126*+12+6*

因此,您必须在RPN中生成所有组合,然后开发一个RPN计算器进行评估。

不幸的是,有很多有6个数字(或其任何子集)的排列。 首先,您可以按任何顺序获得数字,那就是6! = 720 6! = 720组合。 您将始终需要n-1 == 5运算符,并且它们可以是4个运算符中的任何一个。 这就是4**5 == 1024个排列。 最后,这5个运算符可以位于5个位置中的任意一个位置(在第一个数字对之后,在第一个3之后,在4之后,依此类推)。 您在第一个位置最多可以有1个运算符,在第二个位置可以最多两个,依此类推。 那是5! == 120 5! == 120个排列。 因此,总共有720*1024*120 == 88473600排列。 大约是9 * 10**7没有超出计算领域,但是在一台相当快的计算机上生成它们可能要花5分钟左右的时间。

您可以通过“砍掉”搜索树来显着改善这一点

  1. RPN组合的负载在算术上是相同的(例如123456+++++ == 12345+6++++ == 1234+5+6+++等)-您可以使用一些先验知识来改进generate_RPN_combinations,因此没有产生它们
  2. 找出显示某些组合的中间结果永远无法满足您的标准,并且不探索该条道路上的任何其他组合。

然后,您必须将每个字符串发送到RPN计算器。 这些都是非常容易编写的代码,并且是典型的编程练习-将值压入堆栈,当您使用运算符时,从堆栈中弹出顶部的两个成员,应用运算符并将结果压入堆栈。 如果您不想实现-谷歌minimal python rpn calculator并且那里有资源可以帮助您。

请注意,您说不必全部使用6个数字。 我建议不要在评估所有6个数字的组合时检查任何中间结果,如果它们满足标准,则也应保留它们,而不是单独实施。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM