胡闹

前情提要

这周末玩了一个好玩的。

识数鸡说:“我将赋予你加、减、乘、除、乘幂、对数、整数阶乘等七种能力,同时给你四个20以内的数字作为钥匙。”
小宅懵懂地点点头。
世界上还有另外一些拥有这些能力和数字的热血少年,你需要找到他们,用你们的数字钥匙和给定的运算能力算出接近\(π\)的一个数这样你们的电脑才能逃脱Matrix的限制,得到解锁。这样你才能继续上网课还有用电脑刷b站和打游戏了。”
每人领取到的是数,不是数字,不能进行拼接等操作;每个数在公式中只能使用一次;整数阶乘是唯一允许使用的一元运算,加、减、乘、除、乘幂、对数均为二元运算,且运算限制在实数域中。

有点意思,虽然老子现在欠着一箱deadline,但爷还是开干了

我的思路

基于python强大的eval函数和高精度库,肯定要用python写了啊
然后由于是四个数,括号处理问题很复杂
画了画,发现一共有五种括号形式:
\(((AB)C)D\)
\((AB)(CD)\)
\(A((BC)D)\)
\((A(BC))D\)
\(A(B(CD))\)
那么就对这4个数的全排列依次暴力枚举就可以了
二元运算符有\(+,-,*,/,**,log\) ,需要枚举6次
单元运算符有\(fac\) ,枚举两次就可以了

细节

看似这样就结束了,但是实际上细节恶心的很
在运算时候需要加一大坨特判防止炸掉,比如在我没有加特判的情况下电脑就开始算\(16^{27!}\),变得滚烫,算了算这个数大约需要十几个TB的内存
所以就用\(try,except\) 语句一点点试,然后把那些大的离谱或者小的离谱的数直接放缩成阈值就行了。

结果

\(1,14,16,12\)这四个数算出来的是 \(log_{1+log_{14!}16!}12\),是\(3.12014\) 左右,还是有一定差距。
然而我随便试了四个新数,就是\(3.141\) 级别的了。
果真这玩意还是拼脸
不过这是我第一次自己独立用python写代码,整个过程还是挺有趣滴~~

代码

from math import *
from itertools import permutations

pi = acos(-1)
global minn,ans
minn = 100000
ans=''

def fac(n):
    res=1
    if n>=100 or n<0 or abs(n-int(n))>1e-6:
        return 100000000
    for i in range(1,int(n)+1):
        res=res*i
    return res

def dyadic(a,b,op):
    try:
        if op == 0:
            return '(' + a + '+' + b + ')'
        elif op == 1:
            return '(' + a + '-' + b + ')'
        elif op == 2:
            return '(' + a + '*' + b + ')'
        elif op == 3 and eval(b)!=0:
            return '(' + a + '/' + b + ')'
        elif op == 3:
            return '(-10000000000)'
        elif op == 4 and eval(a)!=0 and (abs(eval(b))<50 and abs(eval(a))<999999) and \\
                isinstance(eval(a)**eval(b),complex)==False:
            return '(' + a + '**' + b + ')'
        # elif op==4 and eval(b)<0 and eval(b)>-50 and abs(eval(a))>1/999999 and abs(eval(a))<999999:
        #     return '(' + a + '**' + b + ')'
        elif op==4:
            return '(-10000000000)'
        elif op == 5 and eval(b)!=1 and eval(b)>0 and eval(a)>0 :
            return '(log(' + a + ',' + b + '))'
        else :
            return '(-10000000000)'
    except:
        print(eval(a),eval(b),op)

def unary(a,op):
    if op == 0 :
        return a
    else :
        return '(fac('+a+'))'

def update(str):
    # print(str)
    now_ans = eval(str)
    if(now_ans>4 or now_ans<3):
        return
    print(str)
    print(now_ans)
    global minn,ans
    if abs(now_ans - pi) < abs(minn - pi):
        minn = now_ans
        ans = str

def Up(str):
    update(unary(str,0))
    update(unary(str,1))

def calc(ls):
    print(ls)
    for i in range(6):
        for j1 in range(2):
            for j2 in range(2):
                tmp1=dyadic(unary(ls[0],j1),unary(ls[1],j2),i)
                for k in range(6):
                    for l in range(2):
                        tmp2=dyadic(tmp1,unary(ls[2],l),k)
                        for m in range(6):
                            for n in range(2):
                                tmp3=dyadic(tmp2,unary(ls[3],n),m)
                                Up(tmp3)


    for i in range(6):
        for j1 in range(2):
            for j2 in range(2):
                tmp1 = dyadic(unary(ls[0], j1), unary(ls[1], j2), i)
                for k in range(6):
                    for l1 in range(2):
                        for l2 in range(2):
                            tmp2 = dyadic(unary(ls[2],l1), unary(ls[3], l2), k)
                            for m in range(6):
                                tmp3 = dyadic(tmp1, tmp2, m)
                                Up(tmp3)
    # print("jbsm")
    for i in range(6):
        for j1 in range(2):
            for j2 in range(2):
                tmp1 = dyadic(unary(ls[1], j1), unary(ls[2], j2), i)
                for k in range(6):
                    for l in range(2):
                        tmp2 = dyadic(tmp1, unary(ls[3], l), k)
                        for m in range(6):
                            for n in range(2):
                                tmp3 = dyadic(unary(ls[0],n),tmp2, m)
                                Up(tmp3)

    for i in range(6):
        for j1 in range(2):
            for j2 in range(2):
                tmp1 = dyadic(unary(ls[1], j1), unary(ls[2], j2), i)
                for k in range(6):
                    for l in range(2):
                        tmp2 = dyadic(unary(ls[0],l),tmp1, k)
                        for m in range(6):
                            for n in range(2):
                                tmp3 = dyadic(tmp2, unary(ls[3], n), m)
                                Up(tmp3)

    for i in range(6):
        for j1 in range(2):
            for j2 in range(2):
                tmp1 = dyadic(unary(ls[2], j1), unary(ls[3], j2), i)
                for k in range(6):
                    for l in range(2):
                        tmp2 = dyadic(unary(ls[1], l), tmp1, k)
                        for m in range(6):
                            for n in range(2):
                                tmp3 = dyadic(unary(ls[0], n),tmp2, m)
                                Up(tmp3)

def main():
    number=['1','12','14','16']
    for i in permutations(number):
        calc(i)

    print(ans)
    print(eval(ans))

main()

posted @ 2020-03-15 13:43  小飞淙的云端  阅读(92)  评论(0编辑  收藏