5 पाई खोजने के लिए सेकंड


11

पाई बार (या पाई आप अगर अस्पष्ट अंकन की तरह) 100 दशमलव स्थानों के लिए है:

8.5397342226735670654635508695465744950348885357651149618796011301792286111573308075725638697104739439...

( OIES A019609 ) ( संभावित तर्कहीनता के लिए तर्क )

आपका कार्य एक प्रोग्राम लिखना है जो एक सकारात्मक पूर्णांक एन में लेता है, और एन दशमलव स्थानों के लिए Pi * e को छोटा करता है। जैसे अगर N = 2, तो आउटपुट होना चाहिए 8.53

यह एक अनुकूलन समस्या है, इसलिए सबमिशन जो एन के उच्चतम मूल्य के लिए सही आउटपुट दे सकता है वह जीत जाएगा।

यह सुनिश्चित करने के लिए कि सभी प्रस्तुतियाँ एक ही कंप्यूटिंग शक्ति का उपयोग करके आंकी जाती हैं, आपके कोड को किसी भी भाषा का उपयोग करते हुए विचारधारा पर चलाया जाना चाहिएIdeone faq के अनुसार , उपयोगकर्ताओं में लॉग इन नहीं करने के लिए 5 सेकंड की रन समय सीमा है। यह 5 सेकंड की सीमा वह है जिसका आपको उपयोग करना चाहिए, कि लॉग इन के लिए 15 सेकंड की सीमा। ( अन्य सीमा जैसे मेमोरी, कोड आकार, आदि के लिए faq देखें )

विशेष रूप से, कोई भी व्यक्ति जो ideone में लॉग इन नहीं है, वह आपके प्रोग्राम को ideone पर N के सभी मानों के लिए 1 से कुछ अधिकतम Nmax तक चलाने में सक्षम हो सकता है, और लगभग हर समय सही आउटपुट देखें । किसी भी बिना Time limit exceededया Memory limit exceeded, आदि त्रुटियों। सबसे बड़े Nmax के साथ सबमिशन जीत जाता है।

(क्या लिया गया वास्तविक समय 5 सेकंड से अधिक का है, जब तक कि विचारधारा त्रुटियां नहीं देती है, तब तक कोई फर्क नहीं पड़ता। " लगभग सभी समय " को किसी विशेष N के लिए 95% से अधिक समय के रूप में परिभाषित किया गया है।)

विवरण

  • आप किसी भी गणितीय विधि का उपयोग कर सकते हैं जिसे आप Pi * e की गणना करना पसंद करते हैं, लेकिन हो सकता है कि आप Pi, e या Pi * e के पहले दर्जन अंकों से आगे के आउटपुट को हार्डकोड न करें
    • असीमित संसाधनों को देखते हुए आपका कार्यक्रम किसी भी एन के लिए काम करने में सक्षम होना चाहिए।
    • यदि आपकी भाषा उनके पास होती है तो आप पी या ई स्थिरांक में निर्मित का उपयोग कर सकते हैं।
  • आप अपने कोड के लिए बाहरी वेबसाइट या संसाधनों का उपयोग नहीं कर सकते हैं (यदि आइडोन इसे अनुमति भी देता है)।
  • हार्डकोडिंग और बाहरी संसाधनों तक पहुंचने से परे, कुछ भी जो आइडोन की अनुमति देता है, लगभग निश्चित रूप से ठीक है।
  • आपके इनपुट और आउटपुट को (जाहिर है) काम करना चाहिए जो कि आइडोन i / o के लिए प्रदान करता है (स्टडिन / स्टडआउट केवल ऐसा लगता है)। यह ठीक है अगर आपको इनपुट एन के आसपास उद्धरणों की आवश्यकता है या आउटपुट कुछ ऐसा है ans = ..., आदि।
  • कृपया इनपुट के रूप में अपने Nmax के साथ अपने कोड के एक विचारक स्निपेट का लिंक शामिल करें।
  • यदि कोई टाई होती है (केवल संभावना है कि यदि कई सबमिशन 64kB आउटपुट कैरेक्टर लिमिट को हिट करते हैं) तो उच्चतम वोट उत्तर जीत जाता है।

3
मम ... अस्पष्ट पाई।
डेनिस

यह बहुत आसानी से एक कोड-गोल्फ हो सकता है और यदि ऐसा है तो अधिक मजेदार होगा।
ऑप्टिमाइज़र

2
@ ऑप्टिमाइज़र यह कोड-गोल्फ हो सकता है, लेकिन फिर यह हर दूसरे डिजिट जनरेशन कोड-गोल्फ जैसा होगा। मैं एक समय आधारित प्रतियोगिता का प्रयास करना चाहता था जिसे ऑनलाइन सत्यापित किया जा सके। (हालांकि अधिक कम्प्यूटेशनल रूप से जटिल समस्या बेहतर रही होगी।)
केल्विन के शौक

अगर यह कोड गोल्फ है APL शायद जीत जाएगा (शून्य से सटीक सटीक हिस्सा)
TwiNight

1
मुझे संदेह है कि ये कार्यक्रम पूरी तरह से आईओ से बंधे रहने के लिए अंकों को लिखने के लिए बाध्य होंगे। पांच सेकंड एक लंबे समय के लिए वाई-क्रंचर जैसी चीज है ।
विल

जवाबों:


12

अजगर - 65535

http://ideone.com/knKRhn

from math import exp, log

def divnr(p, q):
  """
    Integer division p/q using Newton-Raphson Division.
    Assumes p > q > 0.
  """

  sp = p.bit_length()-1
  sq = q.bit_length()-1
  sr = sp - sq + 1

  s = []
  t = sr
  while t > 15:
    s = [t] + s
    t = (t>>1) + 1
  # Base-case division
  r = (1 << (t<<1)) / (q >> sq-t)

  for u in s:
    r = (r << u-t+1) - (r*r * (q >> sq-u) >> (t<<1))
    t = u
  return (r * (p >> sq)) >> sr

def pibs(a, b):
  if a == b:
    if a == 0:
      return (1, 1, 1123)
    p = a*(a*(32*a-48)+22)-3
    q = a*a*a*24893568
    t = 21460*a+1123
    return (p, -q, p*t)
  m = (a+b) >> 1
  p1, q1, t1 = pibs(a, m)
  p2, q2, t2 = pibs(m+1, b)
  return (p1*p2, q1*q2, q2*t1 + p1*t2)

def ebs(a, b):
  if a == b:
    if a == 0:
      return (1, 1)
    return (1, a)
  m = (a+b) >> 1
  p1, q1 = ebs(a, m)
  p2, q2 = ebs(m+1, b)
  return (p1*q2+p2, q1*q2)

if __name__ == '__main__':
  n = input()

  pi_terms = int(n*0.16975227728583067)

  # 10^n == e^p
  p = n*2.3025850929940457

  # Lambert W_0(p/e) a la Newton
  k = log(p) - 1
  w = k - (k-1)/(k+1)
  while k > w:
    k = w
    w -= (k - p*exp(-k-1))/(k+1)

  # InverseGamma(e^p) approximation
  e_terms = int(p / w)

  pp, pq, pt = pibs(0, pi_terms)
  ep, eq = ebs(0, e_terms)

  z = 10**n
  p = 3528*z*ep*abs(pq)
  q = eq*abs(pt)

  pie = divnr(p, q)
  print pie,

Ideone gmpy2स्थापित करने के लिए प्रतीत नहीं होता है , जो कम से कम दो कारणों से दुर्भाग्यपूर्ण है। एक, क्योंकि यह कैल्सेशन को बहुत तेज और दो बना देगा, क्योंकि यह किसी भी फार्मूला को एक मनमाना सटीक वर्गमूल अव्यवहारिक बनाने की आवश्यकता है।

के लिए सूत्र मैं उपयोग π था रामानुजन द्वारा सूचीबद्ध फॉर्मूला (39) के रूप में:

जो प्रति शब्द ~ 5.89 अंकों की दर से परिवर्तित होता है । मेरी जानकारी के लिए, यह अपनी तरह की सबसे तेज़ परिवर्तित श्रृंखला है जिसे एक मनमाने ढंग से सटीक वर्गमूल के मूल्यांकन की आवश्यकता नहीं है। फॉर्मूला (44) एक ही पेपर में (अभिसरण दर ~ 7.98 अंक प्रति शब्द) सबसे अधिक बार रामानुजन फॉर्मूला के रूप में संदर्भित किया जाता है

ई के लिए मैं जिस सूत्र का उपयोग करता हूं , वह व्युत्क्रम गुटों का योग है। आवश्यक पदों की संख्या की गणना ( -1 ( 10 n ) के रूप में की जाती है, जो कि मैं मैं गणित पर पाया गया एक सन्निकटन का उपयोग करता हूं । लैम्बर्ट डब्ल्यू 0 घटक न्यूटन की विधि का उपयोग करके पाया जाता है।

इनमें से प्रत्येक योग की गणना फास्ट ई-फंक्शन एवल्यूशन (जिसे आमतौर पर बाइनरी-स्प्लिटिंग के रूप में जाना जाता है) के माध्यम से किया जाता है, जो मूल रूप से करतसुबा द्वारा तैयार किया गया था। विधि एकल तर्कसंगत मूल्य p / q के लिए n शब्दों के लिए एक योग को कम करती है । इन दो मूल्यों को फिर अंतिम परिणाम का उत्पादन करने के लिए गुणा किया जाता है।

अद्यतन:
प्रोफाइलिंग से पता चला कि गणना के लिए आवश्यक आधे से अधिक समय अंतिम प्रभाग में बिताया गया था। केवल पूर्णता प्राप्त करने के लिए q के ऊपरी सबसे लॉग 2 (10 n ) बिट्स की आवश्यकता होती है, इसलिए मैं पहले से कुछ ट्रिम कर देता हूं। कोड अब में Ideone उत्पादन बफर भरता 3.33s

अद्यतन 2:
चूंकि यह एक चुनौती है, मैंने सीपीथॉन की सुस्ती से निपटने के लिए अपनी खुद की विभाजन दिनचर्या लिखने का फैसला किया। divnrऊपर का कार्यान्वयन न्यूटन-रफसन डिवीजन का उपयोग करता है । सामान्य विचार न्यूटन की विधि का उपयोग करके d = 1 / q · 2 n की गणना करने के लिए है , जहां n को बिट्स की संख्या की आवश्यकता होती है और परिणाम की गणना p · d >> n के रूप में की जाती है । रनटाइम अब 2.87 है - और यह गणना से पहले बिट्स को काटने के बिना भी है; यह इस विधि के लिए अनावश्यक है।


4

PARI / GP: 33000

यह मूल रूप से OEIS में दिया गया प्रोग्राम है , इनपुट और फॉर्मेट आउटपुट को सही ढंग से लेने के लिए संशोधित किया गया है। यह हरा करने के लिए आधार रेखा के रूप में काम करना चाहिए, अगर कुछ और नहीं।

मुझे लगता है कि यह सही है। मैंने इसे OEIS के खिलाफ 100 और 20k पर चेक किया, और यह दोनों के लिए मेल खाता था। इसके खिलाफ जांच करने के लिए ऑनलाइन अंकों को खोजना काफी कठिन है।

33,000 के लिए यह 4.5 के बारे में लेता है, इसलिए यह शायद एक छोटा सा टकरा सकता है। मैं सिर्फ इनपुट और आइडोन के धीमे-धीमे जमा / संकलन / रन लूप के साथ फिडिंग से थक गया।

{ 
    m=eval(input());
    default(realprecision, m+80); 
    x=Pi*exp(1);
    s="8.";
    d=floor(x);
    x=(x-d)*10;
    for (n=1, m, d=floor(x); 
         x=(x-d)*10; 
         s=Str(s,d));
    print(s);
}

Ideone.com लिंक


आपके अंक मेरा मेल खाते हैं, इसलिए मैं एक अंग पर बाहर जा रहा हूं और कहता हूं कि वे शायद सही हैं।
प्राइमो

यह कार्यक्रम अनिवार्य रूप से अपने सभी समय को लूप में खर्च करता है, एक-एक करके अंक उत्पन्न करता है। यदि आप Str(floor(frac(x)*10^m)इसे लेते हैं तो यह सैकड़ों / हजारों गुना तेज हो जाता है।
चार्ल्स

2

अजगर ३

चूंकि पी और ई में निर्मित पर्याप्त अंक नहीं हैं, इसलिए मैंने अपनी गणना करने का फैसला किया।

import decimal
import math
decimal.getcontext().prec=1000000
decimal=decimal.Decimal;b=2500
print(str(sum([decimal(1/math.factorial(x)) for x in range(b)])*sum([decimal(1/16**i*(4/(8*i+1)-2/(8*i+4)-1/(8*i+5)-1/(8*i+6))) for i in range(b)]))[0:int(input())+2])

IDEOne लिंक

STDIN = 1000 के लिए आउटपुट:

8.5397342226735669504281233688422467204743749305568824722710929852470173635361001388261308713809518841081669216573834376992066672804294594807026609638293539437286935503772101801433821053915371716284188665787967232464763808892618434263301810056154560438283877633957941572944822034479453916753507796910068912594560500836608215235605783723340714760960119319145912948480279651779184356994356172418603464628747082162475871780202868607325544781551065680583616058471475977367814338295574582450942453416002008665325253385672668994300796223139976640645190237481531851902147391807396201201799703915343423499008135819239684881566321559967077443367982975103648727755579256820566722752546407521965713336095320920822985129589997143740696972018563360331663471959214120971348584257396673542429063767170337770469161945592685537660073097456725716654388703941509676413429681372333615691533682226329180996924321063261666235129175134250645330301407536588271020457172050227357541822742441070313522061438812060477519238440079

Nmax सबसे बड़ा इनपुट मूल्य है जिसे आप अपने प्रोग्राम को दे सकते हैं इससे पहले कि आइडोन इसे नहीं चलाएगा।
केल्विन के शौक

1
@ केल्विन के शौक मुझे लगता है कि nmax मनमाने ढंग से हालांकि बड़ा है ...
बीटा Decay

1
ideone आपको असीम कंप्यूटिंग शक्ति नहीं देता है। आपके कार्यक्रम का सबसे बड़ा इनपुट मान क्या है जो आइडोन पर चल सकता है? (हालांकि वास्तव में आपका कार्यक्रम should be able to work for any N, given unlimited resourcesनियम का पालन नहीं करता है । अधिकांश उत्पादन लगभग शून्य = 10000 पर शून्य है।)
केल्विन के शौक

वह अजगर नहीं है 3 NameError: name 'xrange' not defined:।
बाकुरि

2

स्काला - 1790

पर IDEOne http://ideone.com/A2CIto

हम Mach (और माचिन-फॉर्मूला कोड गंभीर रूप से यहां से पोर्ट किए गए ) के लिए वेथरफील्ड के सूत्र का उपयोग करते हैं । हम साधारण बिजली श्रृंखला का उपयोग करके ई की गणना करते हैं।

object Main extends App {
  import java.math.{BigDecimal => JDecimal}
  import java.math.RoundingMode._
  import scala.concurrent.Future
  import scala.concurrent.Await
  import scala.concurrent.ExecutionContext.Implicits._
  import scala.concurrent.duration._
  val precision = 1800

  def acotPrecision(numDigits: Int)(x: BigDecimal) = {
    val x1 = x.underlying
    val two = JDecimal.valueOf(2)
    val xSquared = x1 pow 2
    val unity = JDecimal.ONE.setScale(numDigits, HALF_EVEN)
    var sum = unity.divide(x1, HALF_EVEN)
    var xpower = new JDecimal(sum.toString)
    var term = unity

    var add = false

    var n = JDecimal.valueOf(3).setScale(numDigits)
    while (term.setScale(numDigits, HALF_EVEN).compareTo(JDecimal.ZERO) != 0) {
      xpower = xpower.divide(xSquared, HALF_EVEN)
      term = xpower.divide(n, HALF_EVEN)
      sum = if (add) sum add term else sum subtract term
      add = !add
      n = n add two
    }
    sum
  }

  def ePrecision(numDigits: Int) = {
    val zero = JDecimal.ZERO
    var sum = zero
    var term = JDecimal.ONE.setScale(numDigits, HALF_EVEN)
    var n = JDecimal.ONE.setScale(numDigits, HALF_EVEN)
    while(term.setScale(numDigits, HALF_EVEN).compareTo(zero) != 0) {
      sum = sum add term
      term = term.divide(n, HALF_EVEN)
      n = n add JDecimal.ONE
    }
    sum
  }

  val acot = acotPrecision(precision) _

  def d(x: Int) = JDecimal.valueOf(x)

  def piFuture = Future(d(4) multiply (
    (d(83) multiply acot(107)) add (d(17) multiply acot(1710)) subtract (d(22) multiply acot(103697))
    subtract (d(24) multiply acot(2513489)) subtract (d(44) multiply acot(18280007883L))
   add (d(12) multiply acot(7939642926390344818L))
   add (d(22) multiply acot(BigDecimal("3054211727257704725384731479018")))
  ))

  def eFuture = Future(ePrecision(precision))

  Await.result(
    for (pi <- piFuture;
         e <- eFuture) yield println((pi multiply e).setScale(precision - 10, DOWN))
  , 5 seconds) 
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.