我正在尝试编写一个程序,它遍历所有可能的简单方程式以找到24的值。我设法完成了循环但是有些东西我没有抓住。
这个想法是一个3级循环(我猜是theta(n ^ 3)?,时间复杂度很差),这用于构建一个4个数字的方程式(在程序的早期随机生成)到我的名单。
numList = [x2, x3, x4]
这是我的代码:
for i in range(4):
for j in range(4):
for k in range(4):
for l in range(len(numList)):
n += 1
print(i, j, k, " i, j, k")
print(x2, x3, x4, "x2, x3, x4")
print(x, "x supposed to be reset")
print(l, "val of l")
print(n, "val of n")
if i == 0 or j == 0 or k == 0:
x += "+"
x += str(numList[n])
print(x, "add")
if i == 1 or j == 1 or k == 1:
x += "-"
x += str(numList[n])
print(x, "sub")
if i == 2 or j == 2 or k == 2:
x += "*"
x += str(numList[n])
print(x, "mult")
if i == 3 or j == 3 or k == 3:
x += "/"
x += str(numList[n])
print(x, "div")
if n == 2:
print()
print("----")
print(x, "final")
print(eval(x), "evald")
if eval(x) is not 24:
x = x1
print(x, "x reset")
else:
print(eval(x), "= 24")
n = -1
print("----")
当由于某种原因,我正在构建和评估(x)的字符串没有重置时,错误进来,而是添加到在最后一个循环迭代中生成的相同字符串(它应该是默认值) 。 x的默认值是随机生成的:
x = str(randrange(1, 9))
这对我来说很奇怪,我不确定出了什么问题,循环就像一个没有中断的switch条件语句。这是我的控制台输出:Pasted to pastebin
有人可以告诉我我做错了吗?或者我的代码中发生了什么我没看到 为什么x没有被重置,好像它是一个正在构建的新字符串(这是我想要的)?
编辑:这是完整的来源:equation.py
答案 0 :(得分:1)
问题不在于'x未被重置'。问题是你的代码并没有设计成在每次传递时只使用三个运算符。例如,如果i为0,j为1且k为2则由于i为0而使用+, - 由于j为1而*由于k为2,因此对于等式中的每个数字,所以你' d看到1+5-5*5+6-6*6+4-4*4
之类的内容,所有操作符重复三次。
你想要更像这样的逻辑,你明确地使用三个运算符并迭代三个运算符的所有组合:
from random import randrange
def brute_force():
x1 = randrange(1, 9)
x2 = randrange(1, 9)
x3 = randrange(1, 9)
x4 = randrange(1, 9)
numList = [x1, x2, x3, x4]
operatorList = ["+", "-", "/", "*"]
equation = ""
for i in range(4):
for j in range(4):
for k in range(4):
equation = str(numList[0]) + operatorList[i] + str(numList[1]) + operatorList[j] + str(numList[2]) + operatorList[k] + str(numList[3])
print("equation: " + equation)
print("evaluation: " + str(eval(equation)))
if __name__ == "__main__":
brute_force()
输出看起来像
>>> brute_force()
equation: 4+6+4+6
evaluation: 20
equation: 4+6+4-6
evaluation: 8
equation: 4+6+4/6
evaluation: 10
equation: 4+6+4*6
evaluation: 34
equation: 4+6-4+6
evaluation: 12
equation: 4+6-4-6
evaluation: 0
equation: 4+6-4/6
evaluation: 10
...
答案 1 :(得分:1)
这是另一种不依赖于eval
的方程式构建器的方法,并且还可以让您轻松使用任何二进制(2个参数)函数以及任何操作顺序:
class Operation():
def __init__(self, func, precedence):
self.func = func
self.precedence = precedence
def __call__(self, *args):
return self.func(*args)
def __repr__(self):
return self.func.__name__
class Equation():
def __init__(self, numbers, operations):
self.nums = list(numbers)
self.ops = list(operations)
def eval(self):
while self.ops:
min_op_precedence = min([x.precedence for x in self.ops])
#get all pairs of numbers in the list [1,2,3] -> [(1,2), (2,3)]
for index, pair in enumerate(zip(self.nums, self.nums[1:])):
if self.ops[index].precedence == min_op_precedence:
#evaluate pair of numbers if the precedence for their op is highest
#ie "1 * 2 - 3" -> "2 - 3"
val = self.ops[index](*pair)
self.nums.pop(index)
self.nums[index] = val
self.ops.pop(index)
break
return self.nums.pop()
以下是如何使用它来查找操作的排列给出某种结果,如果存在这样的排列(使用暴力):
from operator import add, sub, mul, floordiv
from itertools import permutations
numbers = [ 1, 2, 3, 4 ]
#operations with order of operations:
ops = [ Operation(*x) for x in [(mul, 1), (floordiv, 2), (sub, 3), (add, 4)] ]
def findequation( numbers, ops, answer ):
for p in permutations(ops, (len(numbers)-1)):
if Equation( numbers, list(p) ).eval() == answer:
return p
return None
print findequation(numbers, ops, 0)
#>>> (sub, mul, floordiv)
#this means "1 - 2 * 3 / 4" = 0