0

我正在尝试编写一个程序,该程序遍历所有可能的简单方程以找到 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 条件语句。这是我的控制台输出:粘贴到 pastebin

有人可以告诉我我做错了什么吗?或者我的代码中发生了什么我没有看到为什么 x 没有被重置,就好像它是一个正在构建的新字符串(这就是我想要的)?

编辑:这是整个来源:equation.py

4

2 回答 2

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
...
于 2013-05-19T23:51:35.277 回答
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
于 2013-05-20T02:57:41.547 回答