숫자의 슈퍼 루트를 계산


10

수학에서 tetration은 지수화 후 다음 하이퍼 연산자이며 반복 지수로 정의됩니다.

( A는 성공한 N 회)

승산 ( A는 그 자체로 첨가 N 회)

지수화 ( A는 자체 곱한 N 회)

테트 레이션 ( A는 그 자체로 거듭 제곱, N 회)

상호 작용의 역관계를 수퍼 루트, 수퍼 로그라고합니다. 당신의 작업은 B에서 A와 B, 인쇄물을 제공, 프로그램 작성하는 것입니다 A의 - 오더 슈퍼 루트

예를 들면 다음과 같습니다.

  • A = 65,536및 B = 인 4경우2
  • A = 7,625,597,484,987및 B = 인 3경우3

A와 B는 양의 정수이며 결과는 소수점 뒤에 5 자리의 정밀도를 갖는 부동 소수점 숫자 여야합니다. 결과는 실제 도메인에 속합니다.

슈퍼 루트에는 많은 솔루션이있을 수 있으므로주의하십시오.


1
입력 숫자에 최소 / 최대 한계가 있습니까? 유효한 답변이 부동 소수점 답변을 지원해야합니까, 아니면 정수만 지원해야합니까?
Josh

3
여러 솔루션 인 경우 프로그램에서 모두 또는 하나만 찾아야합니까?
Johannes H.

5
그래서 당신의 승리 기준은 무엇입니까?
Mhmd

2
주어진 A 및 B ≥ 1에 대해 둘 이상의 솔루션이있는 수퍼 루트의 간단한 예를 제공 할 수 있습니까?
Tobia

1
수퍼 루트를 수학적으로 표현할 수 있습니까? 나는 그것이 그것이 어떻게 정의되어 있는지 여전히 이해하지 못한다.

답변:


6

C — 명확성을 목표로 코드를 짜내려고하지 않았습니다.

입력 고려 :

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

그런 다음 ℝ에는 일반적으로 하나의 솔루션 만 있어야하므로 문제를 상당히 단순화합니다.

코드는 다음과 같습니다

#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 ½ ) ➙ 2 as n ➙ ∞? (잘 알려진 한계)

$ ./tet_root 2 10
1.416190

$ ./tet_root 2 100
1.414214

$ ./tet_root 2 1000
1.414214

예!

n (e 1 / e ) ➙ ∞ as 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 ...)


당신은 실제로 내가 ∈ (:)이 답변을) 말할 수있는 수학에 대해 많이 알고 (ℝeally 인상적인 물건)
알버트 렌쇼

@AlbertRenshaw 이것은 단지 이분법의 구현입니다. 전혀 어렵지 않습니다.
단순히 아름다운 예술

5

파이썬, 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

답변에 대한 간단한 선형 검색.

주제가 아닌데, * # $ (@!는 파이썬 **연산자에 어떤 영향을 미칩니 까?

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

버그 리포트가 필요하십니까?
Josh

연관성이 방해되고 있습니까? 아마도 당신은 비교 (1e200)**2하고 1e(200**2)있습니까?
danmcardle

2
@ Josh : 버그를보고했습니다 : bugs.python.org/issue20543 기본적으로 의도 된대로 작동합니다 -IEEE float에는별로 적합하지 않습니다. 그들이 무언가를 고치 OverflowError려면 첫 번째 경우 를 생성해야합니다 .
Keith Randall

3

매스 매 티카, 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 에서 시작하여     log C log C log C ⋯ A ≤ 1 이 될 때까지 10 -6 씩 증가 하는 간단한 선형 검색으로, log C 함수가 재귀 적으로 B 번 적용됩니다.

      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 × log (C) + B × log (D))

여기서 B는 근본 순서이고 C는 요구되는 정션 기수이며 D는 정밀한 자릿수입니다. 이 복잡성은 내 직관적 인 이해이며 공식적인 증거를 제시하지 않았습니다.

이 알고리즘에는 큰 정수가 필요하지 않으며 일반 부동 소수점 숫자에 대해서만 로그 함수를 사용하므로 부동 소수점 구현의 한계 (배정 밀도 또는 그것들을 제공하는 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에서 시작하여 2에서 4로, 2에서 3으로)에 의해 직접 적중되는 값 중 하나이기 때문에 정확한 값으로 나타납니다. 발생하지 않는 일반적인 경우 결과는 ⎕CT 오류로 근사값에 근사합니다 (보다 정확하게는 모든 후보 염기의 로그 테스트는 ⎕CT 공차로 수행됨).


1

루비, 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 루프 만 실행하기 때문에 정확도가 떨어집니다.

루비, 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]

인내심이 있고 6 바이트를 절약하려는 경우 실수 솔루션 만 제공하도록 제한을 제거 할 수 있습니다. 중첩 된 함수 중 일부를 약식으로 표현하여 몇 바이트를 더 절약 할 수도 있습니다. 주어진대로

여기에 이미지 설명을 입력하십시오


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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.