Esto viene de http://programmers.blogoverflow.com/2012/08/20-controversial-programming-opinions/
"Dado que Pi se puede estimar usando la función 4 * (1 - 1/3 + 1/5 - 1/7 + ...) con más términos que dan mayor precisión, escriba una función que calcule Pi con una precisión de 5 decimales. "
- Tenga en cuenta que la estimación debe hacerse calculando la secuencia dada anteriormente.
p=lambda:3.14159
Respuestas:
JavaScript,
46 58 5645 bytesActualización de ES6 : Resulta que hay más funciones disponibles para nosotros ahora que han pasado cinco años.
Esta versión ( 45 bytes; sí,
let
se requiere) funciona en modo estricto ES6 en teoría . En la práctica, puede ejecutarlo en V8 (por ejemplo, con nodo) con--use-strict --harmony-tailcalls
; La función de llamadas de cola adecuadas aún no está ampliamente implementada, por desgracia. Sin embargo, es un comportamiento específico, por lo que debería estar bien.Si queremos apegarnos a lo que está ampliamente implementado, y no requiere el modo estricto, simplemente podemos usar la sintaxis de flecha gruesa ES6 para las funciones, pero de lo contrario conservamos la misma implementación que antes (sugerido por Brian H) por un costo de 48 bytes.
La elección del nombre para el parámetro único realmente no importa, pero podríamos elegir uno de los nombres que usamos para minimizar la contaminación de alcance global.
Esta versión es una expresión de función; agregue dos caracteres (por ejemplo, "
f
") si desea que se nombre. Esta versión golpea a los globalesa
yi
; esto podría evitarse si agregamos "a,i
" a la lista de parámetros.Utiliza una versión reformulada del algoritmo para evitar la necesidad de restar.
Aquí hay una versión "simple" sin este ajuste:
que registra
6462 caracteres.Gracias a @ardnew por la sugerencia de deshacerse de
4*
antesreturn
.Historia
fuente
a+=2/i/-~-~i;return 4*a
aa+=8/i/-~-~i;return a
Python 59 bytes
Esto imprime 1000 dígitos; un poco más de lo requerido 5. En lugar de usar la iteración prescrita, usa esto:
los
6637
(el denominador más interno) se puede formular como:Esto implica una convergencia lineal. Cada iteración más profunda producirá un bit binario más de pi .
Si , sin embargo, insiste en usar el bronceado -1 identidad, una convergencia similar puede conseguirse, si no te importa ir sobre el problema de forma ligeramente diferente. Echando un vistazo a las sumas parciales:
4.0, 2.66667, 3.46667, 2.89524, 3.33968, 2.97605, 3.28374, ...
es evidente que cada término salta de un lado a otro a cada lado del punto de convergencia; La serie tiene convergencia alterna. Además, cada término está más cerca del punto de convergencia que el término anterior; Es absolutamente monótono con respecto a su punto de convergencia. La combinación de estas dos propiedades implica que la media aritmética de cualquiera de los dos términos vecinos está más cerca del punto de convergencia que cualquiera de los términos mismos. Para darle una mejor idea de lo que quiero decir, considere la siguiente imagen:
La serie externa es la original, y la serie interna se encuentra tomando el promedio de cada uno de los términos vecinos. Una notable diferencia. Pero lo que es verdaderamente notable es que esta nueva serie también tiene convergencia alterna y es absolutamente monótona con respecto a su punto de convergencia. Eso significa que este proceso se puede aplicar una y otra vez, hasta la saciedad.
Okay. ¿Pero cómo?
Algunas definiciones formales. Deje P 1 (n) ser el n º término de la primera secuencia, P 2 (n) ser el n º término de la segunda secuencia, y de manera similar P k (n) el n º plazo de la k ésimo secuencia como se define anteriormente .
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, ...]
No es sorprendente que estos coeficientes sigan exactamente los coeficientes binomiales, y pueden expresarse como una sola fila del Triángulo de Pascal. Desde una fila arbitraria de triángulo de Pascal es trivial calcular, una arbitrariamente 'profundo' serie se pueden encontrar, simplemente tomando los primeros n parciales sumas, multiplicar cada por el término correspondiente en el k ésimo fila del triángulo de Pascal, y dividiendo por 2 k-1 .
De esta manera, se puede lograr una precisión total de coma flotante de 32 bits (~ 14 lugares decimales) con solo 36 iteraciones, en cuyo punto las sumas parciales ni siquiera han convergido en el segundo lugar decimal. Esto obviamente no es golf:
Si quería precisión arbitraria, esto se puede lograr con una pequeña modificación. Aquí una vez más calculando 1000 dígitos:
El valor inicial de p comienza 2 10 más grande, para contrarrestar los efectos de división entera de s / d a medida que d se hace más grande, haciendo que los últimos dígitos no converjan. Note aquí nuevamente que
3318
también es:El mismo número de iteraciones que el primer algoritmo (reducido a la mitad porque t disminuye en 1 en lugar de 2 en cada iteración). Una vez más, esto indica una convergencia lineal: un bit binario de pi por iteración. En ambos casos, se requieren 3318 iteraciones para calcular 1000 dígitos de pi , como una cuota ligeramente mejor que 1 millón de iteraciones para calcular 5.
fuente
4 * sum(1/(1+i*2) if not i%2 else -1/(1+i*2) for i in xrange(places*10**(places)))
k → ∞
, sef(-1,k)
acerca a su suma Euler.P_1 = ..., P_2 = ..., P_3 = ..., P_4 = ...
, "... multiplique cada uno por el término correspondiente en lakth
fila del Triángulo de Pascal, y dividiendo por2^{k-1}
.", En lugar de lanth
fila y2^{n-1}
?.Mathematica
42 39 34 33 31 2632Enfoque de Arquímedes 26 caracteres
Esto alcanza el criterio cuando la entrada es 822.
Pregunta: ¿Alguien sabe cómo calculó el pecado de 180 grados? Yo no.
Enfoque de Leibniz (serie de Gregory) 32 caracteres
Esta es la misma función que el presentador del problema le dio como ejemplo. Alcanza el criterio en aproximadamente medio millón de iteraciones.
Enfoque Madhava-Leibniz 37 caracteres
¡Esta variación utiliza algunos caracteres más pero converge al criterio en solo 9 iteraciones!
fuente
APL (14)
fuente
--/4÷1-2×⍳1e6
Java (67 caracteres)
Tenga en cuenta que esto evita la pérdida de importancia al sumar los números en el orden correcto.
fuente
while(--i>0)
awhile(i--)
y guardar 2 caracteresHaskell, 32
Contando un nombre de función es
34
fuente
R - 25 caracteres
fuente
C (GCC) (44 caracteres)
Eso es 41 caracteres, pero también debe compilarse
-O2
para que el optimizador elimine la recursividad de la cola. Esto también se basa en un comportamiento indefinido con respecto al orden en que++
se ejecutan; Gracias a Ugoren por señalar esto. He probado con gcc 4.4.3 en Linux de 64 bits.Tenga en cuenta que a menos que el optimizador también reordene la suma, agregará desde el número más pequeño, por lo que evita la pérdida de importancia.
Llamar como
p()
.fuente
q()
, nop()
. Y no creo-O2
que deba contarse (pero si lo cuenta, son 4 caracteres debido al espacio requerido).p(0)
. 3. Guardar un char porreturn++i...
. 4. Dos++i
hace un comportamiento indefinido.q
eso me enseñará a verificar dos veces después de cambiar el nombre. Creo que sigo la práctica normal de contar-O2
como 3 caracteres, pero podemos abrirlo en meta si lo desea; meta.codegolf.stackexchange.com/questions/19 es la única discusión relevante que puedo encontrar. He agregado la versión de gcc que estoy usando, y que me permite llamarla comop()
. Guardar el carácter detiene el optimizador y da segfault. Aclararé que estoy usando un comportamiento indefinido, según meta.codegolf.stackexchange.com/questions/21p()
: ¿está seguro de que llamarp()
desde cualquier contexto funcionaría? ¿O es solo lo que sucedió en la pila en su prueba?p()
vsp(0)
, pero no sé qué comportamiento documenta y no soy realmente un programador en C.J, 26 caracteres
+ / + / _ 2 ((4 _4) &%)>: +: i.100Se movió de 100 elementos de secuencia a 1e6 elementos. Además, ahora es un código etiquetado y podría copiarse desde el navegador a la consola sin errores.
fuente
-/4%>:2*i.1e6
- 13 caracteres. (Gracias a b_jonas en #jsoftware por darme cuenta de que-/
funciona para calcular una suma con signo alternativo. [Esto se debe a que todos los operadores en J tienen la misma precedencia y asociativos a la derecha, entonces-/ 1 2 3 4
<=>1 - (2 - (3 - 4))
<=>1 - 2 + 3 - 4
.])Javascript - 33 caracteres
Llame
p
pasando un número impar positivox
y calculará Pi con(x-1)/2
términos.fuente
Ruby - 82 caracteres
Intentalo : https://repl.it/LQ8w
El enfoque usa la serie dada indirectamente usando un enfoque de aceleración numérica. La salida resultante es
pi ≈ 3.14159265161
vs.
pi = 3.14159265359
Empieza con
Y luego, dado que esto se alterna, podemos acelerar la convergencia usando
Y aplica esto repetidamente:
Y por simplicidad,
f(n) = f(n,n)
.Ruby - 50 caracteres
Si no te importa correr durante mucho tiempo, entonces simplemente puedes usar
o
fuente
C, 69 caracteres
a
se inicializa a 1).void main
es extraño y no estándar, pero hace que las cosas funcionen. Sin ella, la recursión se implementa como una llamada real, lo que lleva a un desbordamiento de pila. Una alternativa es agregarreturn
.4*
pueden guardar dos caracteres , si se ejecuta con tres parámetros de línea de comando.fuente
int main(a)
o inclusomain(a)
, GCC solo da una advertencia. Y dará una advertencia devoid main
todos modos, y tal vez incluso porque solo tiene un argumento para hacerlomain
.Clojure - 79 caracteres
Esto crea una función sin argumentos que calculará un flotante que se aproxima a pi correctamente a cinco decimales. Tenga en cuenta que esto no vincula la función a un nombre como
pi
, por lo tanto, este código debe evaluarse en su lugar con oeval
como(<code>)
un nombre, en cuyo caso la solución espor 82 caracteres
Acerca de
fuente
PHP -
5655 caracteresNo sé si puedo hacerlo mucho más pequeño sin romper la regla del algoritmo.
fuente
<?for(;1e6>$j;)$p+=($i=-$i|4)/~-$j+=2;echo$p;
Perl -
4339 caracteresno estoy seguro de las reglas sobre subrutinas anónimas, pero aquí hay otra implementación que usa la construcción de series de @ FireFly
fuente
Java -
9284 caracteresNo puedo superar con mucho el resultado de Peter Taylor, pero aquí está el mío:
Versión sin golf:
Editar: guardado algunos caracteres con el operador ternario.
fuente
Python - 56 caracteres
Meh, mi python-fu no es lo suficientemente fuerte. No pude ver más atajos, pero ¿quizás un golfista más experimentado podría encontrar algo para recortar aquí?
fuente
4.
->4
). En otras noticias, ¡acabo de encontrar un caso en el que Python 3 realmente supera a Python 2 en el código de golf!Ruby - 54 caracteres
Mi primer intento en la consola
63 caracteres.
fuente
def a;
lugar dedef a()
.Perl (76 caracteres)
(Resultado: 3.14159052)
No es la solución más corta posible, pero puede ser interesante. Es geométrico. Calculo el área debajo de un círculo.
Tengo otro enfoque divertido, pero es muy lento. Cuenta el número de puntos discretos en un cuadrado que están debajo de un cuarto de círculo y calcula pi a partir de él:
Espera el número de iteraciones como argumento de línea de comando. Aquí puede ver cómo el tiempo de ejecución se relaciona con la precisión. ;)
fuente
k (25 caracteres)
4 * + /% (i # 1 -1) '1 + 2 ! I: 1000000Ligeramente más corto:
fuente
Pitón (49)
fuente
CJam - 21
Cálculo bastante directo de la serie dada.
CJam es http://sf.net/p/cjam
fuente
Julia - 30 caracteres
fuente
SQL, 253 bytes
Proporcionaría un Fiddle de SQL, pero esto va demasiados bucles de profundidad al encontrar las fracciones 1/3 1/5 1/7 etc. y da errores lol. Sin embargo, si cambia
@B<100000
a,1000
entonces se ejecuta (obviamente no con el mismo número de dígitos de precisión).fuente
Befunge, 129 bytes
Pruébalo en línea!
En caso de que alguien se pregunte, es un elefante.
fuente