Python 为“问题”制作一个谜题解算器;四个四“;令人费解的事

Python 为“问题”制作一个谜题解算器;四个四“;令人费解的事,python,math,Python,Math,下面是“四四”字谜的解算器代码 它基本上是有效的,但如果投入更大,速度就慢得多 我想做的是,制作一个较小的操作员列表,如下所示 import itertools import math import time from time import time from math import factorial from math import sqrt def pretty(string): string=string.replace("(4)","4") string=stri

下面是“四四”字谜的解算器代码

它基本上是有效的,但如果投入更大,速度就慢得多

我想做的是,制作一个较小的操作员列表,如下所示

import itertools
import math
import time
from time import time
from math import factorial
from math import sqrt


def pretty(string):
    string=string.replace("(4)","4")
    string=string.replace("factorial4","factorial(4)")
    string=string.replace("sqrt4","sqrt(4)")
    return string


def test(n):
    start=time()
    fails=0
    for i in range(0,n+1):
        if(fours(i))!=None:
            print(fours(i))
        else:
            print("Failed: "+str(i))
            fails+=1
    return("\nFailed "+str(fails)+" out of "+str(n)+"\n\nTotal time: "+str(time()-start)       [:4]+"\nAverage time: "+str((time()-start)/n)[:4])

def fours(goal):
    operators = ['-', '/', '+', '*', '-sqrt', '-^', '-factorial', '-.', '/sqrt', '/^',   '/factorial',  '/.', '+sqrt', '+^', '+factorial', '+.', '*sqrt', '*^', '*factorial', '*.']
    brackets = ["{0}{1}{0}{2}{0}{3}{0}",
                "({0}{1}{0}){2}{0}{3}{0}",
                "({0}{1}{0}{2}{0}){3}{0}",
                "({0}{1}({0}{2}{0})){3}{0}",
                "(({0}{1}{0}){2}{0}){3}{0}",
                "{0}{1}({0}{2}({0}{3}{0}))",
                "{0}{1}(({0}{2}{0}){3}{0})",
                "({0}{1}{0}){2}({0}{3}{0})"]
    for combination in itertools.product(operators, repeat=3):
        for bracket in brackets:
            try:
                formula = bracket.format("(4)", *combination).replace(".(4","(.4")
            except ValueError:
                pass
            try:
                if eval(formula)==goal:
                    return(pretty((formula + " = " + str(int(eval(formula))))))
            except:
                pass

print(test(20))
['-','/','+','*','sqrt','^','factorial',"."]
但要做到这一点,我需要这样做,使程序能够将两个操作符放在一行中 这样就可以得出这样的结果

import itertools
import math
import time
from time import time
from math import factorial
from math import sqrt


def pretty(string):
    string=string.replace("(4)","4")
    string=string.replace("factorial4","factorial(4)")
    string=string.replace("sqrt4","sqrt(4)")
    return string


def test(n):
    start=time()
    fails=0
    for i in range(0,n+1):
        if(fours(i))!=None:
            print(fours(i))
        else:
            print("Failed: "+str(i))
            fails+=1
    return("\nFailed "+str(fails)+" out of "+str(n)+"\n\nTotal time: "+str(time()-start)       [:4]+"\nAverage time: "+str((time()-start)/n)[:4])

def fours(goal):
    operators = ['-', '/', '+', '*', '-sqrt', '-^', '-factorial', '-.', '/sqrt', '/^',   '/factorial',  '/.', '+sqrt', '+^', '+factorial', '+.', '*sqrt', '*^', '*factorial', '*.']
    brackets = ["{0}{1}{0}{2}{0}{3}{0}",
                "({0}{1}{0}){2}{0}{3}{0}",
                "({0}{1}{0}{2}{0}){3}{0}",
                "({0}{1}({0}{2}{0})){3}{0}",
                "(({0}{1}{0}){2}{0}){3}{0}",
                "{0}{1}({0}{2}({0}{3}{0}))",
                "{0}{1}(({0}{2}{0}){3}{0})",
                "({0}{1}{0}){2}({0}{3}{0})"]
    for combination in itertools.product(operators, repeat=3):
        for bracket in brackets:
            try:
                formula = bracket.format("(4)", *combination).replace(".(4","(.4")
            except ValueError:
                pass
            try:
                if eval(formula)==goal:
                    return(pretty((formula + " = " + str(int(eval(formula))))))
            except:
                pass

print(test(20))
['-','/','+','*','sqrt','^','factorial',"."]
注意,它们的阶乘就在它们+号之后

我早些时候问过如何做到这一点,有人建议我制作互斥列表,这样不在同一列表中的操作符就可以一个接一个地放置

问题是,如果不彻底重写代码,我似乎无法找到一种有效的方法来实现这一点

如果有人有一个很好的方法来做这件事(或更好的方法来完成同样的事情),请让我知道

另外,我希望这个程序能够把两个4放在一起,生成44这样的数字,但这样做也会给我同样的问题

示例:当我从0到20时,我得到

4/4+factorial(4)/sqrt(4) = 13
但是当我用我想用的系统做的时候

(4-(4-4))-4 = 0
(4-(4-4))/4 = 1
(4-(4-4))-sqrt(4) = 2
4-((4-sqrt(4))/sqrt(4)) = 3
4-((4-4)/4) = 4
4-((4/4)-sqrt(4)) = 5
4-((4-4)-sqrt(4)) = 6
4-((4/4)-4) = 7
4-((4-4)-4) = 8
4-((4-factorial(4))/4) = 9
(4-(4-4))/(.4) = 10

数字10失败是因为它不能将小数放在除法符号之后,而数字9则不同,因为阶乘不能放在后面-

您的程序需要很长时间才能实现更大的目标,因为它会尝试采用3628804的阶乘。Python将在相当长的一段时间内讨论这个问题。在评估以下各项的过程中会发生这种情况:

  • (4) -阶乘((4)+阶乘((4)/(.4)))
  • =4-阶乘(4+阶乘(10))
  • =4-阶乘(3628804)
如果它能挺过去的话,在那之后,事情就更难做了。它不会在你有生之年结束


你需要找到避免这种计算的方法。避免函数的组合(如阶乘(阶乘(x))可能就足够了。避免问题的一个简单方法是编写一个中间函数,比如“lfact”,以限制计算阶乘的大小。lfact将测试参数,如果太大,则引发异常或返回None,否则调用math.factorial。您将在求值公式中调用替换lfact函数。

您能再扩展一点吗?我喜欢这个挑战,但让我们看一些示例,以便了解您的意思:)我添加了一个我需要修复的类型的示例。这是你想要的吗?那么你是想美化字符串还是担心你会以不同的方式得到答案?我真的不在乎它如何回答问题,但正如你所看到的,如果不使用所有运算符,它根本无法回答某些问题。嗯,看起来你喜欢我对另一个问题的回答-也许你想接受它;-)。你有没有理由不使用你引用的维基百科文章中链接的python代码?