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.
p=lambda:3.14159
Antworten:
JavaScript,
46 58 5645 BytesES6-Update : Es hat sich herausgestellt, dass uns nach fünf Jahren mehr Funktionen zur Verfügung stehen.
Diese Version ( 45 Bytes; ja, das
let
ist 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 .
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.
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 Globalsa
undi
; Dies könnte verhindert werden, wenn wira,i
der Parameterliste " " hinzufügen .Verwendet eine umformulierte Version des Algorithmus, um die Notwendigkeit einer Subtraktion zu umgehen.
Hier ist eine "normale" Version ohne diese Anpassung:
Das entspricht
64 bis62 Zeichen.Danke an @ardnew für den Vorschlag, den
4*
vor dem loszuwerdenreturn
.Geschichte
quelle
a+=2/i/-~-~i;return 4*a
zua+=8/i/-~-~i;return a
Python 59 Bytes
Dies druckt 1000 Stellen aus; etwas mehr als die erforderlichen 5. Anstatt die vorgeschriebene Iteration zu verwenden, verwendet es diese:
Der
6637
(innerste Nenner) kann wie folgt formuliert werden: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:
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:
Wenn Sie eine beliebige Genauigkeit wünschen, kann dies mit einer kleinen Modifikation erreicht werden. Hier nochmal 1000 Stellen rechnen:
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
: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.
quelle
4 * sum(1/(1+i*2) if not i%2 else -1/(1+i*2) for i in xrange(places*10**(places)))
k → ∞
,f(-1,k)
nähert sich Ihre Euler-Summe.P_1 = ..., P_2 = ..., P_3 = ..., P_4 = ...
"... multiplizieren Sie jedes mit dem entsprechenden Begriff in derkth
Zeile von Pascals Dreieck und dividieren Sie durch2^{k-1}
." Anstelle vonnth
Zeile und2^{n-1}
?Mathematica
42 39 34 33 31 2632Archimedes Ansatz 26 Zeichen
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.
Madhava-Leibniz-Ansatz 37 Zeichen
Diese Variante verwendet einige weitere Zeichen, konvergiert jedoch in nur 9 Iterationen zum Kriterium!
quelle
APL (14)
quelle
--/4÷1-2×⍳1e6
Java (67 Zeichen)
Beachten Sie, dass dies einen Bedeutungsverlust vermeidet, indem Sie die Zahlen in der richtigen Reihenfolge addieren.
quelle
while(--i>0)
zuwhile(i--)
und 2 Zeichen speichernHaskell, 32
Es zählt einen Funktionsnamen
34
quelle
R - 25 Zeichen
quelle
C (GCC) (44 Zeichen)
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()
.quelle
q()
nichtp()
. Und ich denke nicht,-O2
dass gezählt werden sollte (aber wenn Sie es zählen, sind es 4 Zeichen wegen des erforderlichen Platzes).p(0)
. 3. Speichern Sie ein Zeichen durchreturn++i...
. 4. Zwei++i
macht undefiniertes Verhalten.q
- das bringt mir bei, nach dem Umbenennen noch einmal zu überprüfen. Ich glaube, ich folge der normalen Praxis,-O2
als 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 bezeichnenp()
. 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/21p()
- sind Sie sicher, dass Anrufep()
aus jedem Kontext funktionieren würden? Oder ist es nur das, was in Ihrem Test auf dem Stack war?p()
vs zu produzierenp(0)
, aber ich weiß nicht, welches Verhalten es dokumentiert, und ich bin kein wirklicher C-Programmierer.J, 26 Zeichen
+ / + / _ 2 ((4 _4) &%)>: +: i.100Von 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.
quelle
-/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 4
1 - (2 - (3 - 4))
1 - 2 + 3 - 4
Javascript - 33 Zeichen
Wenn Sie
p
eine positive ungerade Zahl übergebenx
, wird der Pi mit(x-1)/2
Begriffen berechnet .quelle
Ruby - 82 Zeichen
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
Und dann, da dies abwechselnd ist, können wir die Konvergenz mit beschleunigen
Und es gilt immer wieder:
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
oder
quelle
C 69 Zeichen
a
auf 1 initialisiert).void main
ist 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ügenreturn
.4*
Bei Ausführung mit drei Befehlszeilenparametern können zwei Zeichen gespeichert werden.quelle
int main(a)
oder sogarmain(a)
, GCC gibt nur eine Warnung. Und es wirdvoid main
sowieso eine Warnung geben , und vielleicht sogar, weil du nur ein Argument dafür hastmain
.Clojure - 79 Zeichen
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
pi
gebunden wird. Daher muss dieser Code entweder an Ort und Stelle miteval
as ausgewertet werden(<code>)
gebunden wird. In diesem Fall oder an einen Namen gebunden werdenfür 82 Zeichen
Über
quelle
PHP -
5655 ZeichenIch weiß nicht, dass ich es viel kleiner bekommen kann, ohne die Algorithmusregel zu brechen.
quelle
<?for(;1e6>$j;)$p+=($i=-$i|4)/~-$j+=2;echo$p;
Perl -
4339 ZeichenIch bin mir nicht sicher, welche Regeln für anonyme Subroutinen gelten, aber hier ist eine weitere Implementierung, die die @ FireFly-Serienkonstruktion verwendet
quelle
Java -
9284 ZeichenIch kann Peter Taylors Ergebnis bei weitem nicht schlagen, aber hier ist meins:
Ungolfed-Version:
Bearbeiten: Mit dem ternären Operator wurden einige Zeichen gespeichert.
quelle
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?
quelle
4.
->4
) speichern . In anderen Nachrichten habe ich gerade einen Fall gefunden, in dem Python 3 Python 2 im Codegolf schlägt!Ruby - 54 Zeichen
Mein erster Konsolenversuch
63 Zeichen.
quelle
def a;
anstelle von verwendendef a()
.Perl (76 Zeichen)
(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:
Die Anzahl der Iterationen wird als Befehlszeilenargument erwartet. Hier können Sie sehen, wie die Laufzeit mit der Genauigkeit zusammenhängt. ;)
quelle
k (25 Zeichen)
4 * + /% (i # 1 - 1) '1 + 2 ! I: 1000000Etwas kürzer:
quelle
Python (49)
quelle
CJam-21
Ziemlich einfache Berechnung der angegebenen Serie.
CJam ist http://sf.net/p/cjam
quelle
Julia - 30 Zeichen
quelle
SQL, 253 Bytes
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
,1000
wird es ausgeführt (offensichtlich nicht mit der gleichen Anzahl von Stellen Genauigkeit).quelle
Befunge, 129 Bytes
Probieren Sie es online!
Falls sich jemand wundert, ist es ein Elefant.
quelle