我正在编写一个简单的Python脚本,随机生成6个数字(从1到100)和一个更大的数字(从100到1000)。我对此脚本的目标是:
使用至少2个数字和任何简单的数学运算(加,减,乘和除)计算所有可能的组合
输出所有总数在10以上或以下的组合,以匹配'
数字列表不需要用尽,但重复的数字不被接受。如果代码有效或者没有效率,我也不会太在意(如果有人决定发布任何内容 - 如果有人需要,我可以发帖到目前为止 - 最好是用Python发布);只要它有效,我很乐意对其进行优化。
我自己尝试过,只是因为程序快速以RunTime错误结束而失败。我也试过放入一个计数器来在x传递之后停止循环(其中x是一个很小的数字,比如50),但这会让事情变得更糟,因为它会继续无限地进行。
我也做了一些研究,我发现这个(Computing target number from numbers in a set - 倒数第二个答案)是我发现的最接近我要求的但是还没到那里
感谢您的帮助! : - )
编辑:这是我的代码:
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()
答案 0 :(得分:2)
一种非常简洁的方法是使用Reverse Polish Notation or Postfix表示法。如果您使用带有运算符优先级等的常规算法,那么这种表示法可以避免使用您可能想要的括号。
如果你对时间效率不太感兴趣,你可以用蛮力做到这一点。你需要考虑你想要对分区做什么 - 如果两个数字没有完全分开,你想要将结果返回为“无效”'在某种程度上(我猜是这样),还是真的回归了一个分区?注意后者可能会给你一些无效的答案......
考虑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
组合。您将始终需要n-1 == 5
个运营商,他们可以是4个运营商中的任何一个。那就是4**5 == 1024
排列。最后,这5个操作员可以处于5个位置中的任何一个位置(在第一对数字之后,在第3对之后,在4之后,依此类推)。您可以在第一个位置拥有最多1个操作符,在第二个位置拥有两个,依此类推。这是5! == 120
个排列。所以总共有720*1024*120 == 88473600
个排列。大致9 * 10**7
根本不超出计算领域,但可能需要5分钟左右才能在相当快的计算机上生成它们。
你可以通过"切碎"来显着改善这一点。搜索树
123456+++++ == 12345+6++++ == 1234+5+6+++
等) - 您可以使用一些先验知识来改进generate_RPN_combinations,以便它不会生成它们然后您必须将每个字符串发送到RPN计算器。这些是相当容易编码和典型的编程练习 - 您将值推送到堆栈上,当您来到运算符时,从堆栈中弹出前两个成员,应用运算符并将结果推送到堆栈。如果你不想实现它 - 谷歌minimal python rpn calculator
,那里有资源可以帮助你。
注意,您说您不必使用全部6个号码。我不建议单独实施,而是在评估所有6个数字的组合时建议检查任何中间结果,如果它们满足标准,也要保留它们。