Berechnen Sie pi auf 5 Dezimalstellen

15

Dies kommt von http://programmers.blogoverflow.com/2012/08/20-controversial-programming-opinions/

"Da Pi unter Verwendung der Funktion 4 * (1 - 1/3 + 1/5 - 1/7 + ...) mit mehr Termen mit höherer Genauigkeit geschätzt werden kann, schreiben Sie eine Funktion, die Pi mit einer Genauigkeit von 5 Dezimalstellen berechnet. "

  • Beachten Sie, dass die Schätzung durch Berechnung der oben angegebenen Reihenfolge erfolgen muss.
nos
quelle
8
Sie sollten wahrscheinlich noch einige Regeln hinzufügen, sonst erhalten Sie Antworten wie (Python)p=lambda:3.14159
Matt
1
Haben Sie codegolf.stackexchange.com/questions/506/… gesehen , was sehr ähnlich ist? Zumindest sollten Trig-Funktionen für dieses Problem gesperrt werden, da sie triviale Lösungen wie dieses QBASIC-Programm ermöglichen: INT (4E5 * ATN (1)) / 1E5
PleaseStand
Ich denke, Sie sollten verlangen, dass der Algorithmus eine sukzessive Approximation ist: Je länger Sie rechnen, desto näher kommen Sie an pi heran.
DavidC
@DavidCarraher, obwohl dies bei dieser Serie mathematisch unvermeidlich ist, ist es aus numerischer Sicht höchst zweifelhaft. Eine langsam zusammenlaufende Wechselreihe ist ein Aushängeschild für Bedeutungsverlust.
Peter Taylor
2
Dupe, aber es ist so alt, dass es nicht hier ist: stackoverflow.com/q/407518/12274
JB

Antworten:

10

JavaScript, 46 58 56 45 Bytes

ES6-Update : Es hat sich herausgestellt, dass uns nach fünf Jahren mehr Funktionen zur Verfügung stehen.

let f=(i=0,a=0)=>i>1e6?a:f(i+4,a+8/-~i/(i+3))

Diese Version ( 45 Bytes; ja, das letist erforderlich) arbeitet theoretisch im strengen ES6-Modus . In der Praxis kann man es in V8 (zB mit Node) mit ausführen --use-strict --harmony-tailcalls; Die Proper Tailcalls-Funktion ist leider noch nicht weit verbreitet. Da es sich jedoch um ein bestimmtes Verhalten handelt, sollte es in Ordnung sein.

Wenn wir uns an die weit verbreitete Implementierung halten möchten und keinen Strict-Modus benötigen, können wir einfach die ES6-Syntax für Fettpfeile für Funktionen verwenden, aber ansonsten die gleiche Implementierung wie zuvor (vorgeschlagen von Brian H) für 48 Byte beibehalten .

a=>{for(a=i=0;i<1e6;a+=8/++i/~-(i+=3));return a}

Die Wahl des Namens für den einzelnen Parameter spielt eigentlich keine Rolle, aber wir können auch einen der von uns verwendeten Namen auswählen, um die Verschmutzung des globalen Bereichs zu minimieren.


function(){for(a=i=0;i<1e6;a+=8/++i/~-(i+=3));return a}

Diese Version ist ein Funktionsausdruck. Fügen Sie zwei Zeichen hinzu (zB " f"), wenn Sie möchten, dass es benannt wird. Diese Version überfordert die Globals aund i; Dies könnte verhindert werden, wenn wir a,ider Parameterliste " " hinzufügen .

Verwendet eine umformulierte Version des Algorithmus, um die Notwendigkeit einer Subtraktion zu umgehen.

 1/1 - 1/3  +   1/5 - 1/7   +    1/9 - 1/11  + ...
(3/3 - 1/3) + (7/35 - 5/35) + (11/99 - 9/99) + ...
    2/3     +      2/35     +       2/99     + ...
  2/(1*3)   +    2/(5*7)    +     2/(9*11)   + ...

Hier ist eine "normale" Version ohne diese Anpassung:

function(){for(a=0,i=1;i<1e6;i+=2)a+=[,4,,-4][i%4]/i;return a}

Das entspricht 64 bis 62 Zeichen.

Danke an @ardnew für den Vorschlag, den 4*vor dem loszuwerden return.


Geschichte

function(){for(a=i=0;i<1e6;a+=8/++i/~-(i+=3));return a}     // got rid of `i+=4`; restructured
// Old versions below.
function(){for(a=0,i=1;i<1e6;i+=4)a+=8/i/-~-~i;return a}    // got rid of `4*`
function(){for(a=0,i=1;i<1e6;i+=4)a+=2/i/-~-~i;return 4*a}
FireFly
quelle
oO sehr gute Arbeit, die Subtraktion ausklammern.
acolyte
1
großartige Arbeit, muss aber als ordnungsgemäße Funktion geschrieben werden
spätestens
@ardnew: Danke, ich muss dieses Detail übersehen haben, als ich die Problembeschreibung gelesen habe. Ich habe es aktualisiert und es ist jetzt ein aufrufbarer Funktionsausdruck (Lambda); Ich bin mir nicht sicher, ob dies erlaubt ist oder ob es einen Namen haben muss. In diesem Fall sind es ohnehin nur zwei zusätzliche Zeichen.
FireFly
1
@FireFly können Sie auch 2 Zeichen , indem abrasieren a+=2/i/-~-~i;return 4*azua+=8/i/-~-~i;return a
ardnew
@ardnew: oh, großartig; Daran habe ich nicht gedacht. : D
FireFly
8

Python 59 Bytes

print reduce(lambda x,p:p/2*x/p+2*10**999,range(6637,1,-2))

Dies druckt 1000 Stellen aus; etwas mehr als die erforderlichen 5. Anstatt die vorgeschriebene Iteration zu verwenden, verwendet es diese:

pi = 2 + 1/3*(2 + 2/5*(2 + 3/7*(2 + 4/9*(2 + 5/11*(2 + ...)))))

Der 6637(innerste Nenner) kann wie folgt formuliert werden:

Ziffern * 2 * log 2 (10)

Dies impliziert eine lineare Konvergenz. Jede tiefere Iteration erzeugt ein weiteres binäres Bit von pi .

Wenn Sie jedoch darauf bestehen, die tan- 1- Identität zu verwenden, kann eine ähnliche Konvergenz erzielt werden, wenn es Ihnen nichts ausmacht, das Problem etwas anders anzugehen. Betrachten Sie die Teilsummen:

4,0, 2,66667, 3,46667, 2,89524, 3,33968, 2,97605, 3,28374, ...

es ist offensichtlich, dass jeder Term zu beiden Seiten des Konvergenzpunkts hin und her springt; die serie hat wechselnde konvergenz. Außerdem ist jeder Term näher am Konvergenzpunkt als der vorherige Term. es ist absolut monoton in Bezug auf seinen Konvergenzpunkt. Die Kombination dieser beiden Eigenschaften impliziert, dass das arithmetische Mittel zweier benachbarter Terme näher am Konvergenzpunkt liegt als die beiden Terme selbst. Betrachten Sie das folgende Bild, um eine bessere Vorstellung davon zu bekommen, was ich meine:

Teilsummen

Die äußere Reihe ist das Original, und die innere Reihe ergibt sich aus dem Durchschnitt aller benachbarten Begriffe. Ein bemerkenswerter Unterschied. Aber was wirklich bemerkenswert ist, ist, dass diese neue Serie auch eine abwechselnde Konvergenz aufweist und in Bezug auf ihren Konvergenzpunkt absolut monoton ist. Dies bedeutet, dass dieser Prozess ad nauseum immer wieder angewendet werden kann.

In Ordnung. Aber wie?

Einige formale Definitionen. Sei P 1 (n) der n- te Term der ersten Sequenz, P 2 (n) der n- te Term der zweiten Sequenz und P k (n) der n- te Term der k- ten Sequenz wie oben definiert .

P 1 = [P 1 (1), P 1 (2), P 1 (3), P 1 (4), P 1 (5), ...]

P 2 = [(P 1 (1) + P 1 (2)) / 2, (P 1 (2) + P 1 (3)) / 2, (P 1 (3) + P 1 (4)) / 2, (P 1 (4) + P 1 (5)) / 2, ...]

P 3 = [(P 1 (1) + 2P 1 (2) + P 1 (3)) / 4, (P 1 (2) + 2P 1 (3) + P 1 (4)) / 4, (P 1 (3) + 2P 1 (4) + P 1 (5)) / 4, ...]

P 4 = [(P 1 (1) + 3P 1 (2) + 3P 1 (3) + P 1 (4)) / 8, (P 1 (2) + 3P 1 (3) + 3P 1 (4) + P 1 (5)) / 8, ...]

Es überrascht nicht, dass diese Koeffizienten genau den Binomialkoeffizienten folgen und als einzelne Zeile des Pascalschen Dreiecks ausgedrückt werden können. Da eine beliebige Reihe des Pascalschen Dreiecks trivial zu berechnen ist, kann eine beliebige "tiefe" Reihe gefunden werden, indem einfach die ersten n Teilsummen genommen, mit dem entsprechenden Term in der k- ten Reihe des Pascalschen Dreiecks multipliziert und durch 2 dividiert werden k-1 .

Auf diese Weise kann mit nur 36 Iterationen eine vollständige 32-Bit-Gleitkomma-Genauigkeit (~ 14 Dezimalstellen) erreicht werden, bei der die Teilsummen noch nicht einmal auf der zweiten Dezimalstelle konvergieren. Dies ist offensichtlich nicht Golf:

# used for pascal's triangle
t = 36; v = 1.0/(1<<t-1); e = 1
# used for the partial sums of pi
p = 4; d = 3; s = -4.0

x = 0
while t:
  t -= 1
  p += s/d; d += 2; s *= -1
  x += p*v
  v = v*t/e; e += 1

print "%.14f"%x

Wenn Sie eine beliebige Genauigkeit wünschen, kann dies mit einer kleinen Modifikation erreicht werden. Hier nochmal 1000 Stellen rechnen:

# used for pascal's triangle
f = t = 3318; v = 1; e = 1
# used for the partial sums of pi
p = 4096*10**999; d = 3; s = -p

x = 0
while t:
  t -= 1
  p += s/d; d += 2; s *= -1
  x += p*v
  v = v*t/e; e += 1

print x>>f+9

Der Anfangswert von p beginnt 2 10 größer zu sein, um den ganzzahligen Divisionseffekten von s / d entgegenzuwirken, wenn d größer wird, wodurch die letzten Stellen nicht konvergieren. Beachten Sie auch hier Folgendes 3318:

Ziffern * log 2 (10)

Die gleiche Anzahl von Iterationen wie beim ersten Algorithmus (halbiert, weil t bei jeder Iteration um 1 anstatt um 2 abnimmt ). Dies deutet erneut auf eine lineare Konvergenz hin: ein binäres Bit pi pro Iteration. In beiden Fällen sind 3318 Iterationen erforderlich, um 1000 Stellen pi zu berechnen. Dies ist eine geringfügig bessere Quote als 1 Million Iterationen zur Berechnung von 5.

primo
quelle
Das ist viel besser als meine Lösung:4 * sum(1/(1+i*2) if not i%2 else -1/(1+i*2) for i in xrange(places*10**(places)))
Aaron Hall
1
Dies ist meinem Ansatz sehr ähnlich , der zufällig eine andere Form von Ihnen ist. Im Hinblick auf meinen so k → ∞, f(-1,k)nähert sich Ihre Euler-Summe.
Einfach schöne Kunst
1
Sehr cool; Tolle Analyse und Erklärung, danke.
Jeremy Radcliff
Nur eine kleine Sache. Meinten Sie nicht nach dem P_1 = ..., P_2 = ..., P_3 = ..., P_4 = ..."... multiplizieren Sie jedes mit dem entsprechenden Begriff in der kthZeile von Pascals Dreieck und dividieren Sie durch 2^{k-1}." Anstelle von nthZeile und 2^{n-1}?
Jeremy Radcliff
@ JeremyRadcliff Ich habe, ja. Danke für die Korrektur.
Primo
5

Mathematica 42 39 34 33 31 26 32

Archimedes Ansatz 26 Zeichen

N@#*Sin[180 Degree/#]&

Dies erreicht das Kriterium, wenn die Eingabe 822 ist.

Frage: Weiß jemand, wie er die Sünde von 180 Grad berechnet hat? Ich nicht.


Leibniz 'Ansatz (Gregorys Serie) 32 Zeichen

Dies ist die gleiche Funktion, die der Problemsteller als Beispiel angegeben hat. Es erreicht das Kriterium in ungefähr einer halben Million Iterationen.

N@4Sum[(-1)^k/(2k+1),{k,0,10^6}]

Madhava-Leibniz-Ansatz 37 Zeichen

Diese Variante verwendet einige weitere Zeichen, konvergiert jedoch in nur 9 Iterationen zum Kriterium!

N@Sqrt@12 Sum[(-1/3)^k/(2k+1),{k,0,9}]
DavidC
quelle
die alle berechnen es nach dem in der Problemdefinition angegebenen Algorithmus?
Akolyth
@acolyte Leibniz 'Ansatz (jetzt der erste, der aufgeführt wird) ist tatsächlich derjenige, der in der Beschreibung des Problems erwähnt wird. Es ist sehr langsam zu konvergieren. Eine leichte Variation davon (Madhava-Leibniz) konvergiert sehr schnell.
DavidC
Ein Sinus von 180 ° ist ziemlich einfach. Es ist 180 ° / N, die außerhalb der üblichen Verdächtigen für N schwierig werden kann.
JB
Bitte erklären Sie, @JB Tricky zu messen?
DavidC
In diesem Eintrag sollte "32" stehen, da nur Leibniz 'Ansatz die Anforderungen erfüllt (wenn ich die Zeichen im Code wie angegeben zähle, erhalte ich 34, aber beide Leerzeichen können sicher entfernt werden, was in der Tat eine Länge von 32 ergibt).
Celtschk
4

APL (14)

4×-/÷1-⍨2×⍳1e6

 

Marinus
quelle
1
13,--/4÷1-2×⍳1e6
Timtech
4

Java (67 Zeichen)

float r(){float p=0,s=4,i=1E6f;while(--i>0)p+=(s=-s)/i--;return p;}

Beachten Sie, dass dies einen Bedeutungsverlust vermeidet, indem Sie die Zahlen in der richtigen Reihenfolge addieren.

Peter Taylor
quelle
Dies ist auch vollständig kompatibler C-Code. wenn wie C geschrieben, könnten Sie ändern while(--i>0)zu while(i--)und 2 Zeichen speichern
ardnew
1
@ardnew, stimmt, aber mit C gibt es viel interessantere Tricks zu spielen ...
Peter Taylor
4

Haskell, 32

foldr(\k->(4/(2*k+1)-))0[0..8^7]

GHCi> foldr (\ k -> (4 / (2 · k + 1) -)) 0 [0..8 ^ 7]
3.141593130426724

Es zählt einen Funktionsnamen

34

π=foldr(\k->(4/(2*k+1)-))0[0..8^7]
hörte auf, sich gegen den Uhrzeigersinn zu drehen
quelle
3

R - 25 Zeichen

sum(c(4,-4)/seq(1,1e6,2))
Flodel
quelle
3

C (GCC) (44 Zeichen)

float p(i){return i<1E6?4./++i-p(++i):0;}

Das sind 41 Zeichen, aber es muss auch kompiliert werden -O2, damit der Optimierer die Schwanzrekursion eliminiert. Dies hängt auch von undefiniertem Verhalten in Bezug auf die Reihenfolge ab, in der die++ ausgeführt werden. danke an ugoren für den hinweis. Ich habe mit gcc 4.4.3 unter 64-Bit Linux getestet.

Beachten Sie, dass der Optimierer, sofern er die Summe nicht auch neu anordnet, die kleinste Zahl addiert, um einen Bedeutungsverlust zu vermeiden.

Anrufen als p().

Peter Taylor
quelle
Ihr rekursiver Aufruf ist q()nicht p(). Und ich denke nicht, -O2dass gezählt werden sollte (aber wenn Sie es zählen, sind es 4 Zeichen wegen des erforderlichen Platzes).
Ugoren
Außerdem: 1. gcc 4.1.1 optimiert die Rekursion nicht (und ich sehe nicht, wie es gehen könnte), so dass der Stapel überläuft. 2. Es sollte heißen als p(0). 3. Speichern Sie ein Zeichen durch return++i.... 4. Zwei ++imacht undefiniertes Verhalten.
Ugoren
@ugoren, danke für deine Kommentare. In der Reihenfolge: q- das bringt mir bei, nach dem Umbenennen noch einmal zu überprüfen. Ich glaube, ich folge der normalen Praxis, -O2als 3 Zeichen zu zählen, aber wir können es auf Meta eröffnen, wenn Sie wollen; meta.codegolf.stackexchange.com/questions/19 ist die einzige relevante Diskussion, die ich finden kann. Ich habe die Version von gcc hinzugefügt, die ich verwende und die es mir ermöglicht, sie als zu bezeichnen p(). Das Speichern des Zeichens stoppt den Optimierer und gibt einen Segfault aus. Ich werde klarstellen, dass ich undefiniertes Verhalten verwende, wie in meta.codegolf.stackexchange.com/questions/21
Peter Taylor
Ich habe der Meta-Frage zu Flags eine Antwort hinzugefügt. Über p()- sind Sie sicher, dass Anrufe p()aus jedem Kontext funktionieren würden? Oder ist es nur das, was in Ihrem Test auf dem Stack war?
Ugoren
@ugoren, vielleicht habe ich durchweg Glück gehabt. Selbst wenn ich es zweimal hintereinander aufrufe, gibt das zweite immer noch den richtigen Wert zurück. gcc scheint etwas anderen Code für p()vs zu produzieren p(0), aber ich weiß nicht, welches Verhalten es dokumentiert, und ich bin kein wirklicher C-Programmierer.
Peter Taylor
3

J, 26 Zeichen

+ / + / _ 2 ((4 _4) &%)>: +: i.100

Von 100 Sequenzelementen auf 1e6 Elemente verschoben. Auch jetzt ist es ein Code markiert und könnte ohne Fehler vom Browser auf die Konsole kopiert werden.

+/+/_2((4 _4)&%)\>:+:i.1e6
fftw
quelle
3
-/4%>:2*i.1e6- 13 Zeichen. (Dank an b_jonas in #jsoftware, der mir klar gemacht hat, dass es -/funktioniert, eine Summe mit wechselndem Vorzeichen zu berechnen. [Da alle Operatoren in J gleichrangig und -/ 1 2 3 41 - (2 - (3 - 4))1 - 2 + 3 - 4
rechtsassoziativ sind
das ist ordentlich und doppelt so toll. Oder sogar 2 ^ 10 mehr großartig!
31.
@FireFly das ist schön
Jonah
2

Javascript - 33 Zeichen

p=x=>4*(1-(x&2))/x+(x>1?p(x-2):0)

Wenn Sie peine positive ungerade Zahl übergeben x, wird der Pi mit (x-1)/2Begriffen berechnet .

MT0
quelle
2

Ruby - 82 Zeichen

def f(n,k=n)k>0?(f(n,k-1)+f(n+1,k-1))/2:n<0?0:f(n-1,0)+(-1)**n/(2*n+1.0)end;4*f(9)

Versuch es : https://repl.it/LQ8w

Der Ansatz verwendet die angegebene Reihe indirekt unter Verwendung eines numerischen Beschleunigungsansatzes. Die resultierende Ausgabe ist

pi ≈ 3.14159265161

gegen

pi = 3.14159265359

Es beginnt mit

f(n,0) = 1/1 - 1/3 + 1/5 - ... + ((-1)**n)/(2*n+1)

Und dann, da dies abwechselnd ist, können wir die Konvergenz mit beschleunigen

f(n,1) = (f(n,0) + f(n+1,0))/2

Und es gilt immer wieder:

f(n,k) = (f(n,k-1) + f(n+1,k-1))/2

Und der Einfachheit halber f(n) = f(n,n).


Rubin - 50 Zeichen

Wenn es Ihnen nichts ausmacht, für eine sehr lange Zeit zu laufen, dann können Sie einfach verwenden

def f(n)n<0?0:f(n-1)+(-1)**n/(2*n+1.0)end;4*f(1e7)

oder

a=0;for k in 0..1e7 do a+=(-1)**k/(2*k+1.0)end;4*a
Einfach schöne Kunst
quelle
1

C 69 Zeichen

float p,b;void main(a){b++<9e6?p+=a/b++,main(-a):printf("%f\n",4*p);}
  • Ohne Befehlszeilenparameter ausführen (wird also aauf 1 initialisiert).
  • Muss mit Optimierung kompiliert werden.
  • void mainist seltsam und nicht standard, bringt aber die Dinge zum Laufen. Ohne sie wird die Rekursion als echter Aufruf implementiert, was zu einem Stapelüberlauf führt. Eine Alternative ist das Hinzufügen return.
  • 4*Bei Ausführung mit drei Befehlszeilenparametern können zwei Zeichen gespeichert werden.
ugoren
quelle
Sie könnten das verkürzen int main(a)oder sogar main(a), GCC gibt nur eine Warnung. Und es wird void mainsowieso eine Warnung geben , und vielleicht sogar, weil du nur ein Argument dafür hast main.
Nyuszika7h
1

Clojure - 79 Zeichen

(fn [](* 4(apply +(map #(*(Math/pow -1 %1)(/ 1.0(+ 1 %1 %1)))(range 377000)))))

Dies erzeugt eine Funktion ohne Argumente, die einen Gleitkommawert berechnet, der pi korrekt auf fünf Dezimalstellen approximiert. Beachten Sie, dass die Funktion dadurch nicht an einen Namen wie pigebunden wird. Daher muss dieser Code entweder an Ort und Stelle mit evalas ausgewertet werden(<code>) gebunden wird. In diesem Fall oder an einen Namen gebunden werden

(defn p[](* 4(apply +(map #(*(Math/pow -1 %1)(/ 1.0(+ 1 %1 %1)))(range 377000)))))

für 82 Zeichen

Über

(defn nth-term-of-pi [n] (* (Math/pow -1 n) (/ 1.0 (+ 1 n n))))
(defn pi [c] (* 4 (apply + (map nth-term-of-pi (range c)))))
(def  pi-accuracy-constant (loop [c 1000] (if (< (pi c) 3.14159) (recur (inc c)) c)))
; (pi pi-accuracy-constant) is then the value of pi to the accuracy of five decimal places
arrdem
quelle
1

PHP - 56 55 Zeichen

<?for($j=$i=-1;1e6>$j;){$p+=($i=-$i)/($j+=2);}echo$p*4;

Ich weiß nicht, dass ich es viel kleiner bekommen kann, ohne die Algorithmusregel zu brechen.

TwoScoopsofPig
quelle
1
Wie wäre es damit für 45? <?for(;1e6>$j;)$p+=($i=-$i|4)/~-$j+=2;echo$p;
Primo
Ich habe versucht, mir das auszudenken, konnte aber die bitweisen Operationen nicht zum Laufen bringen. Danke für den Vorschlag!
TwoScoopsofPig
Sie können das letzte Semikolon entfernen, um 1 Zeichen zu speichern.
Nyuszika7h
1

Perl - 43 39 Zeichen

Ich bin mir nicht sicher, welche Regeln für anonyme Subroutinen gelten, aber hier ist eine weitere Implementierung, die die @ FireFly-Serienkonstruktion verwendet

sub{$s+=8/((4*$_+2)**2-1)for 0..1e6;$s}

sub p{$s+=(-1)**$_*4/(2*$_+1)for 0..1e6;$s}

seltsam
quelle
0

Java - 92 84 Zeichen

Ich kann Peter Taylors Ergebnis bei weitem nicht schlagen, aber hier ist meins:

double d(){float n=0,k=0,x;while(n<9E5){x=1/(1+2*n++);k+=(n%2==0)?-x:x;}return 4*k;}

Ungolfed-Version:

double d() {
    float n = 0, k = 0, x;
    while (n < 9E5) {
        x = 1 / (1 + 2 * n++);
        k += (n % 2 == 0) ? -x : x;
    }
    return 4 * k;
}

Bearbeiten: Mit dem ternären Operator wurden einige Zeichen gespeichert.

Averroes
quelle
0

Python - 56 Zeichen

Meh, mein Python-Fu ist nicht stark genug. Ich konnte keine Abkürzungen mehr sehen, aber vielleicht könnte ein erfahrener Golfer hier etwas zum Trimmen finden?

t=s=0
k=i=1
while t<1e6:t,s,i,k=t+1,k*4./i+s,i+2,-k
Chucksmash
quelle
Mit Python 3 können Sie ein Byte für die Gleitkommadivision ( 4.-> 4) speichern . In anderen Nachrichten habe ich gerade einen Fall gefunden, in dem Python 3 Python 2 im Codegolf schlägt!
nyuszika7h
0

Ruby - 54 Zeichen

def a()p=0;1000000.times{|i|p+=8/(4*i*(4*i+2))};p;end;

Mein erster Konsolenversuch

def a()i=1;p=0;while i<2**100 do p+=8/(i*(i+2));i+=4;end;p;end;

63 Zeichen.

Perello
quelle
Sie können ein Byte speichern, indem Sie def a;anstelle von verwenden def a().
nyuszika7h
Ein weiteres durch Entfernen des letzten Semikolons.
nyuszika7h
0

Perl (76 Zeichen)

$y=1e4;for$x(0..1e4-1){$y--while sqrt($x**2+$y**2)>1e4;$a+=$y}print 4*$a/1e8

(Ergebnis: 3.14159052)

Nicht die kürzest mögliche Lösung, aber vielleicht interessant. Es ist eine geometrische. Ich berechne die Fläche unter einem Kreis.

Ich habe einen anderen lustigen Ansatz, aber es ist sehr langsam. Es zählt die Anzahl der diskreten Punkte in einem Quadrat, die unter einem Viertelkreis liegen, und berechnet daraus den Pi:

$i=shift;for$x(0..$i){for$y(0..$i){$h++if sqrt($x**2+$y**2)<$i}}print$h*4/$i**2

Die Anzahl der Iterationen wird als Befehlszeilenargument erwartet. Hier können Sie sehen, wie die Laufzeit mit der Genauigkeit zusammenhängt. ;)

$ time perl -e '$i=shift;for$x(0..$i){for$y(0..$i){$h++if sqrt($x**2+$y**2)<$i}}print$h*4/$i**2' 100
3.1796
real    0m0.011s
user    0m0.005s
sys 0m0.003s

$ time perl -e '$i=shift;for$x(0..$i){for$y(0..$i){$h++if sqrt($x**2+$y**2)<$i}}print$h*4/$i**2' 1000
3.14552
real    0m0.354s
user    0m0.340s
sys 0m0.004s

$ time perl -e '$i=shift;for$x(0..$i){for$y(0..$i){$h++if sqrt($x**2+$y**2)<$i}}print$h*4/$i**2' 10000
3.14199016
real    0m34.941s
user    0m33.757s
sys 0m0.097s
memowe
quelle
0

k (25 Zeichen)

4 * + /% (i # 1 - 1) '1 + 2 ! I: 1000000

Etwas kürzer:

+/(i#4 -4)%1+2*!i:1000000
Skeevey
quelle
0

Python (49)

print 4*sum((-1)**i/(2*i+1.)for i in range(9**6))
3,14159 453527
arshajii
quelle
0

CJam-21

1e6{WI#4d*I2*)/}fI]:+

Ziemlich einfache Berechnung der angegebenen Serie.
CJam ist http://sf.net/p/cjam

aditsu
quelle
0

Julia - 30 Zeichen

sum(4./[1:4:1e6] - 4./[3:4:1e6])
Milktrader
quelle
0

SQL, 253 Bytes

DECLARE @B int=3, @A varchar(max), @C varchar(max)='1'
WHILE @B<100000
BEGIN
SELECT @C=@C+(select case when (@B-1)%4=0 then'+'else'-'end)+
(SELECT cast(cast(1.0/@B as decimal(9,8)) as varchar(max)))
SELECT @B=@B+2
END
EXECUTE('SELECT 4*('+@C+')')

Ich würde eine SQL-Geige bereitstellen, aber dies geht zu viele Schleifen tief, die 1/3 1/5 1/7 usw. Brüche finden und gibt Fehler lol. Wenn Sie jedoch auf wechseln @B<100000, 1000wird es ausgeführt (offensichtlich nicht mit der gleichen Anzahl von Stellen Genauigkeit).

phroureo
quelle
0

Befunge, 129 Bytes

p08p109p^v*86%+55:<$$$<
\$\>:#,_@>+\55+/:#^_"."
v>p"~"/:"~"%08p"~"/00p:2\4%-*"(}"
8^90%"~":+2:+g90*+g80*<
>*:**\/+>"~~"00g:"~"`!|

Probieren Sie es online!

Falls sich jemand wundert, ist es ein Elefant.

Cartoon-Elefant

James Holderness
quelle