पावर को बढ़ाएं


12

चुनौती

चैलेंज एक प्रोग्राम लिख रहा है जो एक पॉजिटिव नंबर aऔर एक नोज़ेरो नंबर bऔर आउटपुट a^b(पावर बी के लिए उठाया गया) लेता है । आप केवल + - * / abs()गणितीय कार्यों / ऑपरेटरों के रूप में उपयोग कर सकते हैं । इन्हें केवल स्केलर मानों पर लागू किया जा सकता है, लेकिन संपूर्ण सूचियों या सरणियों पर नहीं।

उदाहरण:

1.234 ^ 5.678 = 3.29980
4.5   ^ 4.5   = 869.874
4.5   ^-4.5   = 0.00114959

प्रासंगिक: http://xkcd.com/217/

विवरण

आप कंसोल में उपयोग करने के लिए एक फ़ंक्शन या एक समान निर्माण लिख सकते हैं। यदि आप कंसोल इनपुट का उपयोग नहीं कर सकते हैं तो आप मान सकते हैं कि दोनों संख्याएं चर में और मानक आउटपुट या फ़ाइल में लिखने के माध्यम से सहेजे जाते हैं। आउटपुट को कम से कम 4 महत्वपूर्ण अंकों के लिए सही होना चाहिए। आप मान सकते हैं कि दोनों aऔर bअशून्य हैं। 1 मिनट से अधिक का रनटाइम स्वीकार्य नहीं है। सबसे कम संख्या में बाइट्स जीतेंगे। कृपया अपने कार्यक्रम और अपने एल्गोरिथ्म की व्याख्या करें।

EDIT: केवल सकारात्मक आधारों पर विचार किया जाना चाहिए। आप मान सकते हैं a>0ध्यान रखें कि दोनों संख्याओं का पूर्णांक होना आवश्यक नहीं है !!!


3
क्या आप हमें दशमलव शक्ति बढ़ाने के लिए कह रहे हैं? जैसे कहो, 4.5 ^ 4.5?
ईंधन

1
क्या इसका मतलब यह है कि अगर आधार ऋणात्मक है तो हमें काल्पनिक संख्याओं का भी उत्पादन करना होगा?
bebe

1
आउटपुट के लिए क्या होना चाहिए -0.5 ** 0.5?
डेनिस

ठीक है मैंने उस मामले के बारे में नहीं सोचा था, धन्यवाद: नकारात्मक आधारों को सही ढंग से लागू नहीं किया जाना चाहिए। @ सटीक, वास्तविक संख्या में दशमलव हो सकता है (कम से कम अधिकांश प्रोग्रामिंग भाषाओं में =)
त्रुटी

मैं b <0: `4.5 ^ -4.5 = 0.0011496 'के साथ एक परीक्षण मामला जोड़ना चाहता हूं
edc65

जवाबों:


3

पायथन, 77

कुछ अन्य उत्तरों के साथ यह लॉग और ऍक्स्प पर आधारित है। लेकिन कार्यों की गणना संख्यात्मक रूप से साधारण अंतर समीकरणों को हल करके की जाती है।

def f(a,b,y=1):
 if a<1:a=1/a;b=-b
 while a>1:a/=1e-7+1;y*=b*1e-7+1
 return y

क्या यह आवश्यकताओं को पूरा करता है? प्रश्न में उदाहरणों के लिए, हाँ। बड़े ए के लिए, इसमें बहुत लंबा समय लगेगा। बड़े या बी के लिए, यह गलत हो जाएगा।

उदाहरण:

a            b            f(a, b)      pow(a, b)      <1e-5 rel error?
       1.234        5.678       3.2998       3.2998   OK
         4.5          4.5      869.873      869.874   OK
         4.5         -4.5   0.00114959   0.00114959   OK
         0.5          0.5     0.707107     0.707107   OK
         0.5         -0.5      1.41421      1.41421   OK
          80            5  3.27679e+09   3.2768e+09   OK
     2.71828      3.14159      23.1407      23.1407   OK

अद्यतन: त्रुटी ने गणित पर अधिक विस्तार के लिए कहा ताकि आप यहां जाएं। मैंने निम्नलिखित प्रारंभिक मूल्य समस्याओं पर विचार किया:

  • x '(t) = x (t), x (0) = 1. के साथ समाधान exp (t) है।
  • y '(t) = by (t), y (0) = 1. समाधान exp (bt) है।

अगर मुझे t का मान मिल सकता है जैसे कि x (t) = a, तो मेरे पास y (t) = exp (bt) = a ^ b होगा। प्रारंभिक मूल्य समस्या को संख्यात्मक रूप से हल करने का सबसे सरल तरीका यूलर की विधि है । आप व्युत्पन्न फ़ंक्शन की गणना करते हैं कि माना जाता है, और फिर व्युत्पन्न की दिशा में एक कदम, कदम , और इसके लिए आनुपातिक है, लेकिन एक छोटे से निरंतर द्वारा बढ़ाया। तो यह है कि मैं क्या करूं, छोटे कदम उठाएं जब तक कि x उतना बड़ा न हो, और फिर देखें कि उस समय y क्या है। खैर, मैंने ऐसा सोचा था। मेरे कोड में, टी को कभी भी स्पष्ट रूप से गणना नहीं की जाती है (यह 1e-7 * जबकि लूप के चरणों की संख्या है), और मैंने इसके बजाय x के लिए गणना करके कुछ वर्णों को बचाया।


यह बहुत अच्छा लग रहा है, मैं एक और अलग दृष्टिकोण देखकर खुश हूं! क्या आप हमें इन अंतर समीकरणों के बारे में थोड़ा और बता सकते हैं? मैं आमतौर पर जानता हूं कि वे क्या हैं, लेकिन मैं यह पता लगाने में सक्षम नहीं था कि आप कैसे प्रोग्राम का उपयोग करते हैं =)
18

@flawr: ठीक है, मैंने गणित के बारे में कुछ और विवरणों के साथ अपडेट किया।
फिर से गरम किया

6

जावास्क्रिप्ट (E6) 155 174 191

संपादित करें 2 जैसा कि @bebe द्वारा सुझाया गया है, पुनरावर्ती फ़ंक्शन (बहुत बुरा लेकिन कम) का उपयोग करके
'बहुत अधिक पुनरावृत्ति' से बचने के लिए आर फ़ंक्शन को बदल दिया
गया है। यह फ़ंक्शन आधार <3000 के लिए अच्छा प्रदर्शन करता है और रेंज -50..50 में घातांक है।
संपादित गोल्फ अधिक और बेहतर परिशुद्धता

कोई भी वास्तविक संख्या एक परिमेय संख्या (और IEEE मानक 'वास्तविक' संख्‍या के परिमेय वास्‍तविकता के साथ अनुमानित हो सकती है)। किसी भी तर्कसंगत संख्या को a और b पूर्णांकों के साथ भिन्न a / b के रूप में व्यक्त किया जा सकता है। x ^ (a / b) रूट b का (x ^ a) या (x का रूट b) ^ a है। पूर्णांक द्वारा पूर्णांक प्रतिरूपण काफी आसान है। अंकीय जड़ को संख्यात्मक तरीकों का उपयोग करके अनुमानित किया जा सकता है।

कोड

P=(x,e)=>(
  f=1e7,e<0&&(x=1/x,e=-e),
  F=(b,e,r=1)=>e?F(b*b,e>>1,e&1?r*b:r):r,
  R=(b,e,g=1,y=1e-30,d=(b/F(g,e-1)-g)/e)=>d>y|d<-y?R(b,e,g+d,y/.99):g,
  F(R(x,f),e*f)
)

फायरफॉक्स या फायरबग कंसोल में टेस्ट करें

for (i=0;i<100;i++)
{
  b=Math.random()*3000
  e=Math.random()*100-50
  p1=Math.pow(b,e) // standard power function, to check
  p2=P(b,e)
  d=(p1-p2)/p1 // relative difference
  if (!isFinite(p2) || d > 0.001) 
    console.log(i, b, e, p1, p2, d.toFixed(3))
}

अच्छा काम, बहुत सटीक नहीं है, लेकिन यह एल्गोरिथ्म अच्छा है =)
त्रुटी

आप यह क्या व्याख्या कर सकते हैं e&1&&(r*=b)करता है, गुणा छोड़कर rद्वारा b?
निर्दोष

1
@flawrif(e&1 != 0) r *= b
bebe

धन्यवाद, मैं उस कारनामे से अवगत नहीं था, लेकिन यह गोल्फ के लिए एक अच्छा लग रहा है =)
त्रुटी

1
यहाँ काम कर रहा कोड है: P=(x,e)=>(F=(b,e,r=1)=>e?F(b*b,e>>1,e&1?r*b:r):r,R=(b,e,g=1,y=1e-16,d=(b/F(g,e-1)-g)/e)=>d>y|d<-y?R(b,e,g+d):g,e<0&&(x=1/x,e=-e),f=1<<24,F(R(x,f),e*f))(मैं थक गया होना चाहिए)
bebe

6

हास्केल, 85 90

मानक एक्सप-लॉग एल्गोरिथ्म। अब अलग नाम के साथ, कुछ और पात्रों को शेविंग:

a%b|a>1=1/(1/a)%b|0<1=sum$scanl((/).((-b*foldr1(\n b->(1-a)*(b+1/n))c)*))1c
c=[1..99]

raiseअब कहा जाता है (%), या %infix संकेतन में, यहां तक ​​कि इसके उपयोग को कम बाइट का उपभोग करते हैं:4.5%(-4.5)

Ungolfed संस्करण भी केवल 172 बाइट्स का उपयोग करता है:

raise a b | a > 1     = 1 / raise (1/a) b
          | otherwise = expo (-b* ln (1-a))

ln x = foldr1 (\n a -> x*a+x/n) [1..99]

expo x = sum $ scanl ((/) . (x*)) 1 [1..99]

4

जेएस (ईएस 6), 103 बाइट्स

t=(x,m,f)=>{for(r=i=s=u=1;i<1<<7+f;r+=s/(u=i++*(f?1:u)))s*=m;return r};e=(a,b)=>t(b,t(a,1-1/a,9)*b-b,0)

उदाहरण :

e(1.234,5.678) = 3.299798925315965
e(4.5,4.5)     = 869.8739233782269
e(4.5,-4.5)    = 0.0011495918812070608

टेलर श्रृंखला का उपयोग करें।
b^x = 1 + ln(b)*x/1! + (ln(b)*x)^2/2! + (ln(b)*x)^3/3! + (ln(b)*x)^4/4! + ...
साथ प्राकृतिक लघुगणक सन्निकटन :
ln(b) = (1-1/x) + (1-1/x)^2/2 + (1-1/x)^3/3 + (1-1/x)^4/4 + ...

मैंने गणना करने के लिए 128 पुनरावृत्तियों का उपयोग किया b^x(अधिक पुनरावृत्तियों के कारण मुश्किल है) और 262144 पुनरावृत्तियों के लिएln(b)


हो सकता है कि आपको गोल्फ कम करना चाहिए, लेकिन अधिक सटीकता जोड़ना e(80,5) ->1555962210.2240903चाहिए : - 3276800000
edc65

@ edc65, आप सही हैं, 5 और वर्णों के लिए निश्चित किया गया है।
माइकल एम।

1
कुछ अलग तरीकों को देखना बहुत अच्छा है!
दोष

3

गोल्फलुआ १२०

मैं इस तथ्य का उपयोग करता हूं

a^b = exp(log(a^b)) = exp(b*log(a))

और अपने ही लिखा था logऔर expकार्य करता है। टर्मिनल में चलने पर मूल्यों aऔर नए bसिरे से दर्ज किए जाने की आवश्यकता है:

\L(x)g=0~@ i=1,50 c=(x-1)/x~@j=2,i c = c*(x-1)/x$g=g+c/i$~g$\E(x)g=1;R=1e7~@i=1,R g=g*(1+x/R)$~g$a=I.r()b=I.r()w(E(b*L(a)))

नमूना चलता है:

4.5, 4.5  ==> 869.87104890175
4.5, -4.5 ==> 0.0011495904124065
3.0, 2.33 ==> 12.932794624815
9.0, 0.0  ==> 1
2.0, 2.0  ==> 3.9999996172672

एक अनगुल्ड Lua संस्करण है,

-- returns log
function L(x)
   g = 0
   for i=1,50 do
      c=(x-1)/x
      for j=2,i do
         c = c*(x-1)/x
      end
      g = g + c/i
   end
   return g
end

-- returns exp
function E(x)
   g=1;L=9999999
   for i=1,L do
      g=g*(1+x/L)
   end
   return g
end

a=io.read()
b=io.read()

print(E(b*L(a)))
print(a^b)

क्या आप कुछ उदाहरण आउटपुट प्रदान कर सकते हैं?
निर्दोष

@flawr: मुझे लगता है कि मैं कर सकता हूँ ... और अब किया
काइल Kanos
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.