计算数字的超级根


10

在数学中,四位运算是幂运算后的下一个超算子,并且定义为迭代幂运算。

另外一个成功ñ次)

乘法一个加入到本身,Ñ次)

乘以本身,Ñ次)

滴定一次取幂,n次)

四元数的逆关系称为超根和超对数。你的任务是写,鉴于A和B,打印出B中的程序ND A的阶超根

例如:

  • 如果A = 65,536和B = 4则打印2
  • 如果A = 7,625,597,484,987和B = 3则打印3

A和B是正整数,结果必须是小数点后5位数精度的浮点数。结果属于真实域。

注意,超级根可能有许多解决方案。


1
输入数字上有最小/最大界限吗?有效答案应该支持浮点答案,还是仅支持整数?
2014年

3
如果有多个解决方案,该程序应该找到全部还是仅找到一个?
Johannes H.

5
那么您的获胜标准是什么?
Mhmd 2014年

2
您能否举一个简单的超级根示例,对于给定的A和B≥1,它具有多个解决方案?
Tobia 2014年

1
您能否给出超根的数学表示形式?恐怕我仍然不明白它的定义。

Answers:


6

C-为了清晰起见,没有试图压缩代码

考虑输入:

A: A ∈ ℝ, A ≥ 1.0
B: B ∈ ℕ, B ≥ 1

这样,通常在should中应该只有一个解决方案,从而大大简化了问题。

代码是:

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#define TOLERANCE    1.0e-09

double tetrate(double, int);

int main(int argc, char **argv)
{
    double target, max, min, mid, working;
    int levels;

    if (argc == 3)
    {
        target = atof(argv[1]); // A
        levels = atoi(argv[2]); // B

        // Shortcut if B == 1
        if (levels == 1)
        {
            printf("%f\n", target);
            return 0;
        }

        // Get a first approximation
        max = 2.0;
        while (tetrate(max, levels) < target)
            max *= 2.0;

        min = max / 2.0;

        // printf("Answer is between %g and %g\n", min, max);

        // Use bisection to get a closer approximation
        do
        {
            mid = (min + max) / 2.0;
            working = tetrate(mid, levels);
            if (working > target)
                max = mid;
            else if (working < target)
                min = mid;
            else
                break;
        }
        while (max - min > TOLERANCE);

        // printf("%g: %f = %f tetrate %d\n", target, tetrate(mid, levels), mid, levels);
        printf("%f\n", mid);
    }

    return 0;
}

double tetrate(double d, int i)
{
    double result = d;

    // If the result is already infinite, don't tetrate any more
    while (--i && isfinite(result))
        result = pow(d, result);

    return result;
}

编译:

gcc -o tet_root tet_root.c -lm

跑步:

./tet_root A B

例如:

4 2

$ ./tet_root 65536 4
2.000000

3 3

$ ./tet_root 7625597484987 3
3.000000

3个 π

$ ./tet_root 1.340164183e18 3
3.141593

n)➙2为n∞?(众所周知的限制)

$ ./tet_root 2 10
1.416190

$ ./tet_root 2 100
1.414214

$ ./tet_root 2 1000
1.414214

是!

n(e 1 / e)∞为n∞?(上限)

$ ./tet_root 9.999999999e199 100
1.445700

$ ./tet_root 9.999999999e199 1000
1.444678

$ ./tet_root 9.999999999e199 10000
1.444668

$ ./tet_root 9.999999999e199 100000
1.444668

凉!(e 1 / e≅1.44466786101 ...)


您实际上对数学了解很多,我可以告诉您:)(这个答案)∈(特别令人印象深刻的东西)
Albert Renshaw

@AlbertRenshaw这只是二等分的实现。一点也不难。
Simply Beautiful Art

5

Python,87个字符

E=lambda x,n:x**E(x,n-1)if n else 1
def S(A,B):
 x=1.
 while E(x,B)<A:x+=1e-5
 return x

简单线性搜索答案。

题外话,但是python **运算符的*#$(@!是什么?

>>> 1e200*1e200
inf
>>> 1e200**2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: (34, 'Numerical result out of range')

值得报告错误吗?
2014年

关联性妨碍了吗?也许你是在比较(1e200)**21e(200**2)
danmcardle 2014年

2
@Josh:我报告了一个错误:bugs.python.org/issue20543 基本上,按预期方式工作-对于IEEE浮动,它们并不多。如果他们要解决任何问题,则OverflowError在第一种情况下将生成一个。
基思·兰德尔

3

Mathematica,35 40

n /. Solve[Nest[#^(1/n) &, a, b] == n]~N~5

生成所有解决方案的列表,精度为5位数字。

n /. Last@Solve[Nest[#^(1/n) &, a, b] == n]~N~5

另外5个字符只能得到更新规则要求的真实解决方案。


2

朱莉亚

julia> t(a,b)=(c=a;for j=1:b-1;c=a^c;end;c)
julia> s(c,b)=(i=1;while t(i,b)!=c;i+=1;end;i)
julia> s(65536,4)
2
julia> s(7625597484987,3)     
3

由于问题仅定义整数的行为,因此忽略了浮点指令。


2

这什么时候成为标准高尔夫?我认为提出最佳算法是代码挑战!


APL,33个字符

{r←⍵⋄⍺{1≥⍵⍟⍣⍺⊢r:⍵⋄⍺∇⍵+i}1+i←1e¯6}

这是一个简单线性搜索,选自C起始= 1 + 10 -6和10递增其-6直到
    日志Ç日志Ç登录Ç ⋯A≤1
,其中该日志Ç函数应用递归乙倍。

例子

      4 {r←⍵⋄⍺{1≥⍵⍟⍣⍺⊢r:⍵⋄⍺∇⍵+i}1+i←1e¯6} 65536
2.0000009999177335
      3 {r←⍵⋄⍺{1≥⍵⍟⍣⍺⊢r:⍵⋄⍺∇⍵+i}1+i←1e¯6} 7625597484987
3.0000000000575113

该代码非常慢,但是对于较小的基数(例如2或3),它会在几秒钟内完成。参见下面的更好的内容。


APL,对数复杂度

根顺序实际上是线性复杂度,结果大小和精度是对数:

    时间= O(B×对数(C)+ B×对数(D))

其中B是根顺序,C是要查询的四元数基数,D是要查询的精度位数。这种复杂性是我的直觉理解,我还没有提供正式的证明。

该算法不需要大整数,仅对常规浮点数使用log函数,因此在非常大的数上非常有效,达到浮点实现的限制(双精度或任意大FP数)。提供它们的APL实现。)

可以通过将⎕CT(比较公差)设置为所需的可接受误差来控制结果的精度(在我的系统上,默认值为1e-14,大约为14个十进制数字)

sroot←{              ⍝ Compute the ⍺-th order super-root of ⍵:
  n←⍺ ⋄ r←⍵          ⍝ n is the order, r is the result of the tetration.
  u←{                ⍝ Compute u, the upper bound, a base ≥ the expected result:
    1≥⍵⍟⍣n⊢r:⍵       ⍝   apply ⍵⍟ (log base ⍵) n times; if ≤1 then upper bound found
    ∇2×⍵             ⍝   otherwise double the base and recurse
  }2                 ⍝ start the search with ⍵=2 as a first guess.
  (u÷2){             ⍝ Perform a binary search (bisection) to refine the base:
    b←(⍺+⍵)÷2        ⍝   b is the middle point between ⍺ and ⍵
    t←b⍟⍣n⊢r         ⍝   t is the result of applying b⍟ n times, starting with r;
    t=1:b            ⍝   if t=1 (under ⎕CT), then b is the super-root wanted;
    t<1:⍺∇b          ⍝   if t<1, recurse between ⍺ and b
    b∇⍵              ⍝   otherwise (t>1) returse between b and ⍵
  }u                 ⍝ begin the search between u as found earlier and its half.
}

我不确定1≥⍵⍟⍣n以上内容是否会因域错误而失败(因为否定参数的日志可能会立即失败,或者会给出复杂的结果,而这不会出现在的域中),但我一直无法找到一个失败的案例。

例子

      4 sroot 65536
1.9999999999999964
      4 sroot 65537
2.000000185530773
      3 sroot 7625597484987
3
      3 sroot 7625597400000
2.999999999843567
      3 sroot 7625597500000
3.000000000027626

“ 3”作为精确值出现是因为它恰好是二进制搜索直接命中的值之一(从2开始,加倍到4,对分到3)。在一般情况下不会发生,因此结果将以⎕CT误差近似于根值(更准确地说,每个候选碱基的对数测试均以⎕CT公差执行。)


1

Ruby,79个字节

->a,b{x=y=1.0;z=a;eval"y=(x+z)/2;x,z=a<eval('y**'*~-b+?y)?[x,y]:[y,z];"*99;p y}

这与下面的程序相同,但准确性较低,因为它仅运行99个循环。

Ruby,87个字节

->a,b{x=y=1.0;z=a;(y=(x+z)/2;x,z=a<eval("y**"*~-b+?y)?[x,y]:[y,z])while y!=(x+z)/2;p y}

在线尝试

这只是对分。取消高尔夫:

-> a, b {
    # y^^b by evaluating the string "y ** y ** ..."
    tetration =-> y {eval "y ** " * (b-1) + ?y}

    lower = middle = 1.0
    upper = a

    while middle != (lower + upper) / 2 do
        middle = (lower + upper) / 2

        if tetration[middle] > a
            upper = middle
        else
            lower = middle
        end
    end

    print middle
}

0

k [52个字符]

{{{((%x)*(z*x-1)+y%z xexp x-1)}[x;y]/[2]}[y]/[y<;x]}

我自己的 n 根的修改版本

例:

{{{((%x)*(z*x-1)+y%z xexp x-1)}[x;y]/[2]}[y]/[y<;x]}[7625597484987;3]
3f 

{{{((%x)*(z*x-1)+y%z xexp x-1)}[x;y]/[2]}[y]/[y<;x]}[65536;4]
2f

0

哈斯克尔

简单线性搜索,返回第一个,找到最小的匹配项。

{-
    The value of a is the result of exponentiating b some number of times.
    This function computes that number.
-}
superRoot a b = head [x | x<-[2..a], tetrate x b == a]

{-
    compute b^b^...^b repeated n times
-}
tetrate b 1 = b
tetrate b n = b^(tetrate b (n-1))

*Main> superRoot 65536 4
2
*Main> superRoot 7625597484987 3
3

0

Mathematica,41个字节,无优化

Mathematica基本上是为解决此类问题而发明的。一种简单的解决方案是将问题构造为嵌套幂级数,然后将其传递给内置Reduce函数,该函数寻求方程的解析解。结果,除了异常简洁的代码外,以下内容也不是蛮力的。

Reduce[Nest[Power[#, 1/x] &, a, b] == x, x, Reals]

如果您有耐心并且想要保存六个字节,则可以删除该限制以仅提供实数解决方案。您还可以用缩写形式表达一些嵌套函数,以节省更多字节。如给定的,它因此返回

在此处输入图片说明


0

05AB1E,16 个字节

1[ÐU²FXm}¹@#5(°+

@KeithRandall的Python答案端口。

在线尝试。

说明:

1                 # Push a 1
 [                # Start an infinite loop:
  Ð               #  Triplicate the top value on the stack
   U              #  Pop and store one in variable `X`
    ²F            #  Inner loop the second input amount of times:
      Xm          #   And take the top value to the power `X`
        }         #  After the inner loop:
         ¹@       #  If the resulting value is larger than or equal to the first input:
           #      #   Stop the infinite loop
                  #   (after which the top of the stack is output implicitly as result)
            5(°+  #  If not: increase the top value by 10^-5

ÐU²FXm}也可能D²>и.»m是相同的字节数:

  D               #   Duplicate the top value on the stack
   ²>             #   Push the second input + 1
     и            #   Repeat the top value that many times as list
                #   Reduce it by:
        m         #    Taking the power
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.