पाई के अच्छे तर्कसंगत अनुमान


22

एक प्रोग्राम लिखें जो हर के हर अच्छे तर्कसंगत सन्निकटन को बढ़ाता है। a/bपी का एक "अच्छा तर्कसंगत सन्निकटन" है अगर यह किसी भी अन्य की तुलना में किसी भी तर्कसंगत से पीआई के करीब है जो इससे बड़ा नहीं है b

आउटपुट में कुल 167 लाइनें होनी चाहिए, और इस तरह शुरू और अंत होनी चाहिए:

3/1
13/4
16/5
19/6
22/7
179/57
...
833719/265381
1146408/364913
3126535/995207

सबसे छोटा कार्यक्रम जीतता है।

जवाबों:


23

गोल्फस्क्रिप्ट, 71 70 69 वर्ण

2\!:^2^..292^15.2/3]{(.)2/.9>+{\+.((}*;.}do;;]-1%{^0@{2$*+\}/"/"\n}/;

(मान लें कि आप इसे स्टड पर कुछ भी पास नहीं करते हैं)

मैं उन लोगों द्वारा कोई और अधिक सनसनी नहीं सुनना चाहता, जिनके पास पीआई के लिए अंतर्निहित स्थिरांक नहीं हैं। मेरे पास फ्लोटिंग पॉइंट नंबर भी नहीं हैं!

Http://en.wikipedia.org/wiki/Continued_fraction#Best_rational_approximations पृष्ठभूमि के लिए देखें ।

# No input, so the stack contains ""
2\!:^2^..292^15.2/3]
# ^ is used to store 1 because that saves a char by allowing the elimination of whitespace
# Otherwise straightforward: stack now contains [2 1 2 1 1 1 292 1 15 7 3]
# Pi as a continued fraction is 3+1/(7+1/(15+1/(...)))
# If you reverse the array now on the stack you get the first 10 continuants followed by 2
# (rather than 3)
# That's a little hack to avoid passing the denominator 1000000

{
    # Stack holds: ... [c_n c_{n-1} ... c_0]
    (.)2/.9>+
    # Stack holds ... [c_{n-1} ... c_0] c_n (1+c_n)/2+((1+c_n)/2 > 9 ? 1 : 0)
    # (1+c_n)/2 > 9 is an ad-hoc approximation of the "half rule"
    # which works in this case but not in general
    # Let k = (1+c_n)/2+((1+c_n)/2 > 9 ? 1 : 0)
    # We execute the next block k times
    {
        # ... [c_{n-1} ... c_0] z
        \+.((
        # ... [z c_{n-1} ... c_0] [c_{n-1} ... c_0] z-1
    }*
    # So we now have ... [c_n c_{n-1} ... c_0] [(c_n)-1 c_{n-1} ... c_0] ...
    #                    [(c_n)-k+1 c_{n-1} ... c_0] [c_{n-1} ... c_0] c_n-k
    ;
    # Go round the loop until the array runs out
    .
}do

# Stack now contains all the solutions as CFs in reverse order, plus two surplus:
# [2 1 2 1 1 1 292 1 15 7 3] [1 2 1 1 1 292 1 15 7 3] ... [6 3] [5 3] [4 3] [3] [2] []
# Ditch the two surplus ones, bundle everything up in an array, and reverse it
;;]-1%

# For each CF...
{
    # Stack holds ... [(c_n)-j c_{n-1} ... c_0]
    # We now need to convert the CF into a rational in canonical form
    # We unwind from the inside out starting with (c_n)-j + 1/infinity,
    # representing infinity as 1/0
    ^0@
    # ... 1 0 [c_n-j c_{n-1} ... c_0]
    # Loop over the terms of the CF
    {
        # ... numerator denominator term-of-CF
        2$*+\
        # ... (term-of-CF * numerator + denominator) numerator
    }/

    # Presentation
    "/"\n
    # ... numerator "/" denominator newline
}/

# Pop that final newline to avoid a trailing blank line which isn't in the spec
;

1
खैर, तकनीकी रूप से गोल्फस्क्रिप्ट में पीआई के लिए फ़्लोटिंग पॉइंट संख्या और निरंतर दोनों हैं। इसे कहते हैं "#{Math.PI}"
कोनराड बोरोस्की

2
@GlitchMr, किस तरह से एक स्ट्रिंग एक फ्लोटिंग पॉइंट नंबर है?
पीटर टेलर

मैं वास्तव में टिप्पणियों के साथ इसे अनियंत्रित देखना चाहूंगा।
प्राइमो

गजब का। पहले 2\!:^2^..292^15.2/3]ही लाइन ने मेरा दिमाग उड़ा दिया।
प्राइमो

@PeterTaylor ने टाई किया । क्या हम बेहतर कर सकते हैं?
आठ

11

गणितज्ञ, ६hem ६३

यह तेज़ नहीं है, लेकिन मेरा मानना ​​है कि यह तकनीकी रूप से सही है।

Round[π,1/Range@1*^6]//.x_:>First/@Split[x,#2≥#&@@Abs[π-{##}]&]

Round[π, x]के चरणों में closest के निकटतम अंश देता है x। यह "लिस्टेबल" है इसलिए Round[π,1/Range@1*^6]ऐसा सभी फ्रैक्चर के लिए होता है 1/10^6। तब कई "खराब" तर्कसंगत अनुमानों के साथ परिणामी सूची //.को किसी भी तत्व को हटाने के लिए बार-बार ( ) संसाधित किया जाता है जो पूर्ववर्ती की तुलना में ther से दूर हैं।


बहुत अच्छा है, लेकिन मैं इसका परीक्षण नहीं कर सकता क्योंकि मेरे पास गणितज्ञ नहीं है।
कीथ रान्डेल

@ कीथ, यहाँ तर्क है। Round[Pi, x]के Piचरणों में निकटतम अंश देता है x। यह "लिस्टेबल" है, इसलिए Round[Pi,1/Range@1*^6]यह क्रम में 1/10 ^ 6 तक के सभी अंशों के लिए करता है। तब कई "खराब" तर्कसंगत अनुमानों के साथ परिणामी सूची को बार-बार ( //.) उन तत्वों को हटाकर संसाधित किया जाता है जो पूर्ववर्ती की तुलना में पाई से दूर हैं।
श्री। छिपकली

Mathematica, GolfScript की पिटाई। साफ।
स्पेलिंग डी

61 में: Select[Round[f=Pi,1/Range@1*^6],If[#<f,f=#;True]&@Abs[#-Pi]&]... लेकिन बेकार में प्रमुख पूर्वाग्रह दिए गए
डॉ। Belisarius

येर, मटी। थार इस कोड में जादू हो।
माइकल स्टर्न

7

पर्ल, 77 वर्ण

$e=$p=atan2 0,-1;($f=abs$p-($==$p*$_+.5)/$_)<$e&&($e=$f,say"$=/$_")for 1..1e6

एक छोटी सी चुनौती यह है कि पर्ल एक अंतर्निहित नहीं है π , निरंतर उपलब्ध तो मैं पहले के रूप में यह गणना करने के लिए किया था atan2(0,-1)। मुझे यकीन है कि यह नौकरी के लिए अधिक उपयुक्त भाषाओं द्वारा पीटा जाएगा, लेकिन यह मुख्य रूप से पाठ प्रसंस्करण के लिए डिज़ाइन की गई भाषा के लिए बुरा नहीं है।


1
आप को बदल सकता है 999999करने के लिए 1e6और 3 वर्ण सहेजें।
टोटो

@ M42: धन्यवाद! नीचे 82 वर्णों के लिए अब।
इल्मरी करोनन

वास्तव में अच्छा, $ = पूर्णांक प्राप्त करने के लिए। क्षमा करें, मैं दो बार उत्थान नहीं कर सकता।
टोटो

मैं इसे चलाने के लिए नहीं मिल सकता:String found where operator expected at prog.pl line 1, near "say"$=/$_""
कीथ रान्डेल

@KeithRandall: कमांड के लिए आपको -M5.01स्विच (और पर्ल 5.10.0 या बाद में) की आवश्यकता है say। इसका उल्लेख नहीं करने के लिए क्षमा करें।
इल्मरी करोनें

5

पायथन, 96 93 89 वर्ण

a=b=d=1.
while b<=1e6:
 e=3.14159265359-a/b;x=abs(e)
 if x<d:print a,b;d=x
 a+=e>0;b+=e<0

पायथन, 95 93 वर्ण, अलग एल्गोरिथ्म

p=3.14159265359;d=1
for a in range(3,p*1e6):
 b=round(a/p);e=abs(p-a/b)
 if e<d:print a,b;d=e

नोट: यह लिखने की p=3.14159265359;तुलना में कम वर्ण था from math import*। बहुत बुरा लगता है उन आयात!


1
कुछ कमी: 1.0-> 1., 10**6->1e6
कीथ रान्डेल

मैंने आपके सुधारों के साथ अपडेट किया है। बहुत धन्यवाद।
स्टीवन रंबलस्की

@KeithRandall, लेकिन उनमें से दूसरा आउटपुट कल्पना का उल्लंघन करता है।
पीटर टेलर

दूसरे दृष्टिकोण में चर p की कोई आवश्यकता नहीं है। वह 4 चरस है।
पूर्व

@PeterTaylor: मुझे समझ नहीं आया। यह युक्ति का उल्लंघन कैसे करता है?
स्टीवन रूंबल्स्की

4

जेएस (95 अक्षर)

for(i=k=1,m=Math;i<1e6;i++)if((j=m.abs((x=m.round(m.PI*i))/i-m.PI))<k)k=j,console.log(x+'/'+i)

यह 167 लाइनें प्रिंट करता है।


4

रूबी 1.9, 84 वर्ण

m=1;(1..1e6).map{|d|n=(d*q=Math::PI).round;k=(n-q*d).abs/d;k<m&&(m=k;puts [n,d]*?/)}

@ अभिनेता टेलर तुम सही हो। आपको रूबी 1.9 का उपयोग करना होगा।
हावर्ड

4

C99, 113 अक्षर

main(d,n){double e=9,p=2*asin(1),c,a=1;for(;n=d*p+.5,c=fabsl(p-a*n/d),d<1e6;++d)c<e&&printf("%d/%d\n",n,d,e=c);}

के साथ संकलन करने की आवश्यकता है -lm, और शायद अपरिभाषित व्यवहार से भरा है, लेकिन यह मेरे लिए काम करता है।


2

स्काला - 180 वर्ण

import math._
def p(z:Int,n:Int,s:Double):Unit=
if(n==1e6)0 else{val q=1.0*z/n
val x=if(abs(Pi-q)<s){println(z+"/"+n)
abs(Pi-q)}else s
if(Pi-q<0)p(z,n+1,x)else p(z+1,n,x)}
p(3,1,1)

// अपुष्ट: 457

val pi=math.Pi
@annotation.tailrec
def toPi (zaehler: Int = 3, nenner: Int = 1, sofar: Double=1): Unit = {
  if (nenner == 1000000) () 
  else {
    val quotient = 1.0*zaehler/nenner
    val diff = (pi - quotient)
    val adiff= math.abs (diff)
    val next = if (adiff < sofar) {
      println (zaehler + "/" + nenner) 
      adiff 
    }
    else sofar
    if (diff < 0) toPi (zaehler, nenner + 1, next) 
    else toPi (zaehler + 1, nenner, next) 
  }  
}

टेलरेक एनोटेशन सिर्फ एक जांच है, यह सत्यापित करने के लिए, कि यह पूंछ-पुनरावर्ती है, जो अक्सर एक प्रदर्शन में सुधार होता है।


मुझे यह काम करने के लिए नहीं मिल सकता है:pi.scala:1 error: not found: value math
कीथ रान्डेल

क्या आप स्केल 2.8 का उपयोग कर रहे हैं?
प्रयोक्ता अज्ञात

मेरा स्कैला "अज्ञात संस्करण" कहता है, अजीब है। Ideone.com पर, वे 2.8.0 का उपयोग करते हैं और मुझे अभी भी त्रुटियां हैं।
कीथ रान्डेल

इसे Simplescala.com पर आज़माएं - मेरे लिए काम करता है। स्केला-2.8 के लिए, की जगह mathके साथ Mathपर्याप्त हो सकता है। मैंने इस मेटाथ्रेड पर सरलता से उल्लेख किया है, यदि आप इसे फिर से खोजते हैं
उपयोगकर्ता अज्ञात

ठीक है, वह काम करता है।
कीथ रान्डेल

2

मेथेमेटिका 18 17 वर्ण

मैंने "सर्वश्रेष्ठ" के एक उपाय के रूप में, fraction के निरंतर अंश प्रतिनिधित्व में शब्दों की संख्या के रूप में, का उपयोग करना चुना। इस कसौटी के अनुसार, ational के सर्वश्रेष्ठ तर्कसंगत अनुमान इसके अभिसरण हैं।

Less के 10 अभिसरण हैं जो एक मिलियन से कम के भाजक के साथ हैं। यह अनुरोधित 167 शर्तों से कम है, लेकिन मैं इसे यहां शामिल कर रहा हूं क्योंकि यह दूसरों के लिए ब्याज की हो सकती है।

Convergents[π, 10] 

(* out *)
{3, 22/7, 333/106, 355/113, 103993/33102, 104348/33215, 208341/66317,
312689/99532, 833719/265381, 1146408/364913}

यदि आप वास्तव में पहले अभिसरण के लिए भाजक देखना चाहते हैं, तो इसके लिए अतिरिक्त 11 वर्णों की लागत होगी:

Convergents[π, 10] /. {3 -> "3/1"}
(* out *)
{"3/1", 22/7, 333/106, 355/113, 103993/33102, 104348/33215,
208341/66317, 312689/99532, 833719/265381, 1146408/364913}

जो लोग रुचि रखते हैं, उनके लिए निम्नलिखित अभिसरण, आंशिक उद्धरण, और conver के अभिसरण के निरंतर अंश अभिव्यक्ति के बीच संबंधों को दर्शाता है:

Table[ContinuedFraction[π, k], {k, 10}]
w[frac_] := Row[{Fold[(#1^-1 + #2) &, Last[#], Rest[Reverse[#]]] &[Text@Style[#, Blue, Bold, 14] & /@ ToString /@ ContinuedFraction[frac]]}];
w /@ FromContinuedFraction /@ ContinuedFraction /@ Convergents[π, 10]

अंशों को जारी रखा

कृपया निरंतर अंशों के असंगत स्वरूपण का बहाना करें।


यह एक समाधान के लिए लगभग आधा रास्ता है, लेकिन यह सबसे आसान आधा है। मेरा गोल्फस्क्रिप्ट समाधान हार्ड-कोड को केवल 2 वर्णों में जारी अंश का उपयुक्त प्रतिनिधित्व करता है।
पीटर टेलर

लेकिन आपने इस प्रश्न के समाधान के लिए निरंतर अंशों का उपयोग नहीं किया, क्या आपने?
डेविड एसीसी

हाँ। यह ऐसा करने का स्पष्ट तरीका था।
पीटर टेलर

संक्षिप्त होने के अलावा, यह पोस्ट किए गए अधिकांश या अन्य समाधानों की तुलना में बहुत तेज है।
माइकल स्टर्न

1

सी # 140 129 चर

double n=3,d=1,e=d;while(n<4e5){double w=n/d-Math.PI,a=Math.Abs(w);if(a<e){e=a;Console.WriteLine(n+"/"+d);}if(w>0)d++;else n++;}

असम्बद्ध कोड

var numerator = 3d;
var denominator = 1d;
var delta = 4d;
while (numerator < 4e5) 
{
    var newDelta = (numerator / denominator) - Math.PI;
    var absNewDelta = Math.Abs(newDelta);
    if (absNewDelta < delta)
    {
        delta = absNewDelta;
        Console.WriteLine(string.Format("{0}/{1}", numerator, denominator));
    }

    if (newDelta > 0)
    {
        denominator++;
    }
    else
    {
        numerator++;
    }
}

2
varहमेशा आपका दोस्त नहीं होता अपने पक्ष में इसे हटाकर doubleघोषणाओं को मर्ज करने की क्षमता हासिल करते हैं, डबल शाब्दिक उपयोग करने की आवश्यकता खो देते हैं, और 16 वर्णों को बचा सकते हैं। OTOH सवाल एक कार्यक्रम के लिए पूछता है, तो आप एक वर्ग घोषणा और एक Mainविधि को जोड़ने के लिए कुछ खो देंगे ।
पीटर टेलर

1

जे, ६ ९ ६५

नया

]`,@.(<&j{.)/({~(i.<./)@j=.|@-l)@(%~(i:3x)+<.@*l=.1p1&)"0>:_i.1e3

फिर भी एक क्रूर बल दृष्टिकोण लेकिन बहुत तेज और कम बालक।

पुराना

एक सरल "जानवर बल":

(#~({:<<./@}:)\@j)({~(i.<./)@j=.|@-l)@(%~(i:6x)+<.@*l=.1p1&)"0>:i.1e3

a/bएस की सूची बनाएं और फिर उन लोगों को छोड़ दें जो कुछ के लिए and से आगे हैं b'<b

नोट: बदलें 1e3करने के लिए 1e6पूरी सूची के लिए। जाओ कुछ और करो और बाद में लौट जाओ।

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