Isso vem de http://programmers.blogoverflow.com/2012/08/20-controversial-programming-opinions/
"Dado que o Pi pode ser estimado usando a função 4 * (1 - 1/3 + 1/5 - 1/7 + ...) com mais termos dando maior precisão, escreva uma função que calcule o Pi com uma precisão de 5 casas decimais. "
- Observe que a estimativa deve ser feita calculando a sequência fornecida acima.
p=lambda:3.14159
Respostas:
JavaScript,
46 58 5645 bytesAtualização do ES6 : Acontece que há mais recursos disponíveis agora que cinco anos se passaram.
Esta versão ( 45 bytes; sim,
let
é necessária) funciona no modo estrito do ES6 em teoria . Na prática, você pode executá-lo na V8 (por exemplo, com nó) com--use-strict --harmony-tailcalls
; o recurso Adequado Tailcalls ainda não foi amplamente implementado, infelizmente. No entanto, é um comportamento especificado, portanto tudo deve estar bem.Se quisermos manter o que é amplamente implementado, e não exigir o modo estrito, podemos simplesmente usar a sintaxe ES6 da seta de fatura para funções, mas manter a mesma implementação de antes (sugerida por Brian H) por um custo de 48 bytes.
A escolha do nome para o parâmetro único não importa realmente , mas podemos escolher um dos nomes que usamos para minimizar a poluição no escopo global.
Esta versão é uma expressão de função; adicione dois caracteres (por exemplo, "
f
") se desejar que ele seja nomeado. Esta versão derruba os globaisa
ei
; isso pode ser evitado se adicionarmos "a,i
" à lista de parâmetros.Utiliza uma versão reformulada do algoritmo para contornar a necessidade de subtração.
Aqui está uma versão "simples" sem esse ajuste:
com
6462 caracteres.Obrigado a @ardnew pela sugestão de se livrar do
4*
antes doreturn
.História
fonte
a+=2/i/-~-~i;return 4*a
paraa+=8/i/-~-~i;return a
Python 59 bytes
Isso imprime 1000 dígitos; um pouco mais do que o necessário 5. Em vez de usar a iteração prescrita, ele usa o seguinte:
O
6637
(o denominador mais interno) pode ser formulado como:Isso implica uma convergência linear. Cada iteração mais profunda produzirá mais um bit binário de pi .
Se , no entanto, você insistir em usar aidentidade tan -1 , uma convergência semelhante poderá ser alcançada, se você não se importar em abordar o problema de maneira ligeiramente diferente. Analisando as somas parciais:
4.0, 2.66667, 3.46667, 2.89524, 3.33968, 2.97605, 3.28374, ...
é evidente que cada termo pula para frente e para trás em ambos os lados do ponto de convergência; a série tem convergência alternada. Além disso, cada termo está mais próximo do ponto de convergência do que o termo anterior; é absolutamente monotônico em relação ao seu ponto de convergência. A combinação dessas duas propriedades implica que a média aritmética de dois termos vizinhos está mais próxima do ponto de convergência do que qualquer um dos termos em si. Para ter uma idéia melhor do que quero dizer, considere a seguinte imagem:
A série externa é a original e a série interna é encontrada calculando a média de cada um dos termos vizinhos. Uma diferença notável. Mas o que é realmente notável é que essa nova série também possui convergência alternada e é absolutamente monotônica em relação ao seu ponto de convergência. Isso significa que esse processo pode ser aplicado repetidamente, ad nauseum.
Está bem. Mas como?
Algumas definições formais. Deixe- P 1 (n) ser o n th termo da primeira sequência, P 2 (n) ser o n th termo da segunda sequência, e semelhante P k (n) o N ° termo do k th sequência tal como acima definido .
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, ...]
Não surpreendentemente, esses coeficientes seguem exatamente os coeficientes binomiais e podem ser expressos como uma única linha do triângulo de Pascal. Como uma linha arbitrária do Triângulo de Pascal é trivial de calcular, uma série arbitrariamente 'profunda' pode ser encontrada, simplesmente tomando as primeiras n somas parciais, multiplicando cada pelo termo correspondente na k- ésima linha do Triângulo de Pascal e dividindo por 2 k-1 .
Dessa forma, a precisão total do ponto flutuante de 32 bits (~ 14 casas decimais) pode ser alcançada com apenas 36 iterações, momento em que as somas parciais nem convergiram para a segunda casa decimal. Obviamente, isso não é um jogo de golfe:
Se você queria precisão arbitrária, isso pode ser alcançado com uma pequena modificação. Aqui, mais uma vez, calculando 1000 dígitos:
O valor inicial de p começa 2 10 maior, para neutralizar os efeitos da divisão inteira de s / d à medida que d se torna maior, fazendo com que os últimos dígitos não convergam. Observe aqui novamente que
3318
também é:O mesmo número de iterações que o primeiro algoritmo (dividido pela metade porque t diminui em 1 em vez de 2 em cada iteração). Mais uma vez, isso indica uma convergência linear: um bit binário de pi por iteração. Em ambos os casos, são necessárias 3318 iterações para calcular 1000 dígitos de pi , como uma cota ligeiramente melhor que 1 milhão de iterações para calcular 5.
fonte
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)
aproxima da sua soma de Euler.P_1 = ..., P_2 = ..., P_3 = ..., P_4 = ...
"... multiplique cada um pelo termo correspondente nakth
linha do Triângulo de Pascal e divida por2^{k-1}
.", Em vez denth
linha e2^{n-1}
?.Mathematica
42 39 34 33 31 2632Abordagem de Arquimedes 26 caracteres
Isso atinge o critério quando a entrada é 822.
Pergunta: Alguém sabe como ele calculou o pecado de 180 graus? Eu não.
Abordagem de Leibniz (série de Gregory) 32 caracteres
Esta é a mesma função que o poser do problema deu como exemplo. Atinge o critério em aproximadamente meio milhão de iterações.
Abordagem Madhava-Leibniz 37 caracteres
Essa variação usa mais alguns caracteres, mas converge para o critério em apenas 9 iterações!
fonte
APL (14)
fonte
--/4÷1-2×⍳1e6
Java (67 chars)
Note that this avoids loss of significance by adding the numbers up in the correct order.
fonte
while(--i>0)
towhile(i--)
and save 2 charsHaskell, 32
Counting a function name it's
34
fonte
R - 25 chars
fonte
C (GCC) (44 chars)
That's 41 chars, but it also has to be compiled with
-O2
to get the optimiser to eliminate the tail recursion. This also relies on undefined behaviour with respect to the order in which the++
are executed; thanks to ugoren for pointing this out. I've tested with gcc 4.4.3 under 64-bit Linux .Note that unless the optimiser also reorders the sum, it will add from the smallest number, so it avoids loss of significance.
Call as
p()
.fonte
q()
, notp()
. And I don't think-O2
should be counted (but if you do count it, it's 4 chars because of the required space).p(0)
. 3. Save a char byreturn++i...
. 4. Two++i
makes undefined behavior.q
- that'll teach me to double-check after renaming. I think I'm following normal practice in counting-O2
as 3 chars, but we can open it up on meta if you want; meta.codegolf.stackexchange.com/questions/19 is the only relevant discussion I can find. I've added the version of gcc which I'm using, and which allows me to call it asp()
. Saving the char stops the optimiser and gives segfault. I will clarify that I'm using undefined behaviour, as per meta.codegolf.stackexchange.com/questions/21p()
- are you sure callingp()
from any context would work? Or is it just what happened to be on the stack in your test?p()
vsp(0)
, but I don't know what behaviour it documents and I'm not really a C programmer.J, 26 chars
+/+/_2((4 _4)&%)>:+:i.100Moved from 100 items of sequence to 1e6 items. Also now it's a code tagged and could be copypasted from browser to the console without errors.
fonte
-/4%>:2*i.1e6
-- 13 characters. (Thanks to b_jonas in #jsoftware for making me realise that-/
works to compute a sum with alternating sign. [This is since all operators in J are of equal precedence and right-associative, so-/ 1 2 3 4
<=>1 - (2 - (3 - 4))
<=>1 - 2 + 3 - 4
.])Javascript - 33 Characters
Call
p
passing a positive odd numberx
and it will calculate Pi with(x-1)/2
terms.fonte
Ruby - 82 chars
Try it : https://repl.it/LQ8w
The approach uses the given series indirectly using a numerical acceleration approach. The resulting output is
pi ≈ 3.14159265161
vs.
pi = 3.14159265359
It starts with
And then, since this is alternating, we can accelerate the convergence using
And it repeatedly applies this:
And for simplicity,
f(n) = f(n,n)
.Ruby - 50 chars
If you don't mind running for a really long while, then you could simply use
or
fonte
C, 69 chars
a
is initialized to 1).void main
is strange and non-standard, but makes things work. Without it, the recursion is implemented as a real call, leading to a stack overflow. An alternative is addingreturn
.4*
can be saved, if running with three command line parameters.fonte
int main(a)
or evenmain(a)
, GCC only gives a warning. And it will give a warning forvoid main
anyway, and maybe even because you have only one argument tomain
.Clojure - 79 chars
This creates a function of no arguments which will calculate a float which approximates pi correctly to five decimal places. Note that this does not bind the function to a name such as
pi
, so this code must either be evaluated in place witheval
as(<code>)
or bound to a name in which case the solution isfor 82 chars
About
fonte
PHP -
5655 charsI don't know that I can get it much smaller without breaking the algorithm rule.
fonte
<?for(;1e6>$j;)$p+=($i=-$i|4)/~-$j+=2;echo$p;
Perl -
4339 charsnot sure the rules on anonymous subroutines, but here's another implementation using @FireFly's series construction
fonte
Java -
9284 charsI cannot beat by far Peter Taylor's result, but here is mine:
Ungolfed version:
Edit: Saved a few characters using ternary operator.
fonte
Python - 56 chars
Meh, My python-fu is not strong enough. I couldn't see any more shortcuts but maybe a more experienced golfer could find something to trim here?
fonte
4.
->4
). In other news, I just found a case where Python 3 actually beats Python 2 in code golf!Ruby - 54 chars
My first try on console
63 chars.
fonte
def a;
instead ofdef a()
.Perl (76 chars)
(Result: 3.14159052)
Not the shortest possible solution, but maybe interesting. It's a geometrical one. I calculate the area under a circle.
I got another funny approach, but it's really slow. It counts the number of discrete points in a square that are below a quarter circle and calculates pi from it:
It expects the number of iterations as command line argument. Here you can see how run time relates to accuracy. ;)
fonte
k (25 chars)
4*+/%(i#1 -1)'1+2!i:1000000Slightly shorter:
fonte
Python (49)
fonte
CJam - 21
Pretty straightforward calculation of the given series.
CJam is http://sf.net/p/cjam
fonte
Julia - 30 characters
fonte
SQL, 253 bytes
I would provide a SQL Fiddle, but this goes too many loops deep finding the 1/3 1/5 1/7 etc. fractions and gives errors lol. However, if you change
@B<100000
to1000
then it runs (obviously not to the same number of digits of accuracy).fonte
Befunge, 129 bytes
Try it online!
In case anyone is wondering, it's an elephant.
fonte