किसी संख्या की सुपर जड़ की गणना करें


10

गणित में, प्रतिरूपण के बाद टेट्रेशन अगला हाइपर ऑपरेटर है, और इसे पुनरावृत्त प्रतिपादक के रूप में परिभाषित किया गया है।

जोड़ ( एक सफल n बार)

गुणा ( अपने आप में जोड़ा गया, n बार)

प्रतिपादक ( अपने आप से गुणा, n गुना)

Tetration ( एक अपने आप में exponentiated, एन बार)

टेट्रेशन के विलोम संबंधों को सुपर-रूट और सुपर-लॉगरिथम कहा जाता है। आपका कार्य एक प्रोग्राम लिखना है, जो ए और बी दिया गया है, बी एन -मोड को सुपर-रूट ए प्रिंट करता है।

उदाहरण के लिए:

  • यदि A = 65,536और B = 4यह प्रिंट करता है2
  • यदि A = 7,625,597,484,987और B = 3यह प्रिंट करता है3

A और B सकारात्मक पूर्णांक हैं और परिणाम दशमलव बिंदु के बाद 5 अंकों की सटीकता के साथ फ्लोटिंग पॉइंट नंबर होना चाहिए। परिणाम वास्तविक डोमेन का है।

सावधान रहें, सुपर-जड़ों के कई समाधान हो सकते हैं।


1
क्या इनपुट नंबरों पर न्यूनतम / अधिकतम सीमाएं हैं? क्या एक मान्य उत्तर समर्थन फ़्लोटिंग पॉइंट उत्तर, या केवल पूर्णांक होना चाहिए?
जोश

3
यदि कई समाधान, कार्यक्रम सभी या सिर्फ एक मिल जाना चाहिए?
जोहान्स एच।

5
तो आपके जीतने का मापदंड क्या है?
Mhmd

2
क्या आप एक सुपर-रूट का एक सरल उदाहरण दे सकते हैं जिसमें दिए गए ए और बी? 1 के लिए एक से अधिक समाधान हैं?
टोबिया

1
क्या आप सुपर-रूट का गणितीय प्रतिनिधित्व दे सकते हैं? मुझे डर है कि मुझे अभी भी समझ नहीं आया कि इसे कैसे परिभाषित किया जाता है।

जवाबों:


6

सी - स्पष्टता के लिए लक्ष्य, कोड को निचोड़ने का प्रयास नहीं किया

इनपुट पर विचार:

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

फिर आमतौर पर in में केवल एक समाधान होना चाहिए, जो समस्या को काफी सरल करता है।

कोड है:

#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

उदाहरण के लिए:

$ ./tet_root 65536 4
2.000000

$ ./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 ) e e as n ∞ e ? (ऊपरी सीमा)

$ ./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

ठंडा! (ई 1 / ई 44 1.44466786101 ...)


आप वास्तव में गणित के बारे में बहुत कुछ जानते हैं जो मैं बता सकता हूं :) (यह उत्तर) ℝ (a ईर्ष्यापूर्ण प्रभावशाली सामान)
अल्बर्ट

@ अल्बर्ट रेनशॉ यह सिर्फ द्वंद्व का कार्यान्वयन है। बहुत कठिन नहीं है।
बस

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')

बग रिपोर्ट के लायक?
जोश

क्या सहानुभूति रास्ते में मिल रही है? शायद आप तुलना कर रहे हैं (1e200)**2करने के लिए 1e(200**2)?
danmcardle

2
@ जोश: मैंने बग की सूचना दी: bugs.python.org/issue20543 मूल रूप से, इरादा के अनुसार काम कर रहे हैं - वे IEEE फ्लोट के लिए ज्यादा नहीं हैं। यदि वे कुछ भी तय करते हैं, तो यह OverflowErrorपहले मामले में उत्पन्न करना होगा ।
कीथ रान्डेल

3

गणितज्ञ, ३५ ४०

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

यह कोड गोल्फ कब बना? मैंने सोचा कि यह सबसे अच्छा एल्गोरिथ्म के साथ आने के लिए एक कोड चुनौती थी!


एपीएल, 33 वर्ण

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

यह एक सरल रेखीय खोज है, जो C = 1 + 10 -6 से शुरू होती है और इसे 10 -6 तक बढ़ाती है, जब तक कि
    लॉग C लॉग C लॉग C C A
log 1 नहीं होता है, जहां लॉग 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 के लिए यह कुछ ही सेकंड में पूरा हो जाता है। एक बेहतर चीज के लिए नीचे देखें।


एपीएल, लॉगरिदमिक जटिलता

वास्तव में जड़ क्रम पर रैखिक जटिलता, परिणाम आकार और सटीकता पर लघुगणक:

    समय = O (B × log (C) + B × log (D))

जहाँ B मूल क्रम है, C को tetration base कहा जा रहा है, और D, सटीक पूछे जाने वाले अंकों की संख्या है। यह जटिलता मेरी सहज समझ है, मैंने इसका औपचारिक प्रमाण नहीं दिया है।

इस एल्गोरिथ्म को बड़े पूर्णांक की आवश्यकता नहीं है, यह केवल नियमित फ्लोटिंग पॉइंट नंबरों पर लॉग फ़ंक्शन का उपयोग करता है, इसलिए यह बहुत बड़ी संख्याओं पर काफी कुशल है, फ़्लोटिंग पॉइंट कार्यान्वयन की सीमा तक (या तो डबल परिशुद्धता, या मनमाना बड़े एफपी नंबर पर) एपीएल कार्यान्वयन जो उन्हें प्रदान करते हैं।)

⎕CTवांछित स्वीकार्य त्रुटि पर सेटिंग (तुलना सहिष्णुता) द्वारा परिणाम की शुद्धता को नियंत्रित किया जा सकता है (मेरे सिस्टम पर यह 1ely14 तक चूक जाता है, लगभग 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 से द्विगुणित) से सीधे हिट होने वाले मानों में से एक होता है। सामान्य स्थिति में ऐसा नहीं होता है, इसलिए परिणाम aCT त्रुटि के साथ मूल मान को अनुमानित करेगा (अधिक सटीक रूप से, हर उम्मीदवार के आधार का लघुगणक परीक्षण tolerCT सहिष्णुता के साथ किया जाता है।)


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}

इसे ऑनलाइन आज़माएं

यह केवल द्विभाजन है। Ungolfed:

-> 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

गणितज्ञ, अनुकूलन के बिना 41 बाइट्स

इस तरह की समस्याओं को हल करने के लिए मूल रूप से गणितज्ञ का आविष्कार किया गया था। एक आसान समाधान समस्या को नेस्टेड पावर श्रृंखला के रूप में निर्मित करना और इसे अंतर्निहित Reduceफ़ंक्शन के पास करना है, जो समीकरणों के विश्लेषणात्मक समाधान की तलाश करता है। नतीजतन, असामान्य रूप से संक्षिप्त कोड होने के अलावा, निम्नलिखित भी क्रूर बल नहीं है।

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

यदि आप धैर्य रखते हैं और केवल छह बाइट्स बचाना चाहते हैं, तो आप केवल रियल नंबर समाधान प्रदान करने के लिए प्रतिबंध को हटा सकते हैं। आप कुछ और बाइट्स को सहेजने के लिए संक्षिप्त रूप में कुछ नेस्टेड फ़ंक्शन भी व्यक्त कर सकते हैं। जैसा कि दिया गया है, यह इसी प्रकार लौटता है

यहाँ छवि विवरण दर्ज करें


0

05AB1E , 16 बाइट्स

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

पोर्ट @KeithRandall के पायथन जवाब

इसे ऑनलाइन आज़माएं।

स्पष्टीकरण:

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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.