Encontre o enésimo decimal de pi

33

Já existem 30 desafios dedicados a pi, mas nenhum pede que você encontre o n-ésimo decimal, então ...

Desafio

Para qualquer número inteiro no intervalo de 0 <= n <= 10000exibição, o enésimo decimal de pi.

Regras

  • Os decimais são todos os números após 3.
  • Seu programa pode ser uma função ou um programa completo
  • Você deve gerar o resultado na base 10
  • Você pode obter nde qualquer método de entrada adequado (stdin, input (), parâmetros de função, ...), mas não codificado
  • Você pode usar a indexação baseada em 1 se for nativa do seu idioma de escolha
  • Você não precisa lidar com entradas inválidas ( n == -1, n == 'a'ou n == 1.5)
  • Builtins são permitidos, se eles suportarem até pelo menos 10 mil decimais
  • O tempo de execução não importa, pois esse é o código mais curto e não o mais rápido
  • Este é o , o código mais curto em bytes ganha

Casos de teste

f(0)     == 1
f(1)     == 4 // for 1-indexed languages f(1) == 1
f(2)     == 1 // for 1-indexed languages f(2) == 4
f(3)     == 5
f(10)    == 8
f(100)   == 8
f(599)   == 2
f(760)   == 4
f(1000)  == 3
f(10000) == 5

Para referência, aqui estão os primeiros 100 mil dígitos de pi.

Bassdrop Cumberwubwubwub
fonte
Built-ins? por exemplostr(pi())[n+2]
primo 04/07
6
Os destinos duplos mais próximos da IMO são a computação de dígitos truncados somando poderes de pi (sobrecarrega o parâmetro ou seria apenas uma diferença finita aplicada a esse desafio), transmitem pi com precisão (adiciona um índice e suprime algumas impressões) e criptografia de janelas Pi .
Peter Taylor
3
@Suever ofcourse! Essa regra é apenas para salientar que 10k é o mínimo que seu programa deve ser capaz de executar #
Bassdrop Cumberwubwubwub
4
Sugiro adicionar f (599) aos casos de teste, pois pode ser fácil cometer erros (você precisa de cerca de três casas decimais de precisão extra).
aditsu 04/07
2
Também é fácil arredondar incorretamente f (760) = 4, que inicia a sequência 4 999999 8.
Anders Kaseorg

Respostas:

22

05AB1E, 3 bytes

žs¤

Explicado

žs   # push pi to N digits
  ¤  # get last digit

Experimente online

Usa indexação baseada em 1.
Suporta até 100k dígitos.

Emigna
fonte
Pi para n dígitos não arredondam?
busukxuan
7
@busukxuan No. Ele usou uma constante predefinida de pi para 100k dígitos e recupera N deles.
Emigna
4
@ Emigna Isso é muito útil. Boa solução.
Suever 04/07
2
Curto e Sharp, PCG no seu melhor
Xylius
16

Python 2, 66 bytes

n=input()+9
x=p=5L**7
while~-p:x=p/2*x/p+10**n;p-=2
print`x/5`[-9]

A entrada é retirada do stdin.


Uso da amostra

$ echo 10 | python pi-nth.py
8

$ echo 100 | python pi-nth.py
8

$ echo 1000 | python pi-nth.py
3

$ echo 10000 | python pi-nth.py
5
primo
fonte
Tenha cuidado ao usar n no algoritmo ... de saída para 599 deve ser de 2, não 1. Além disso, você pode querer especificar que você está usando python 2.
aditsu
@aditsu updated. Confirmado para todos os n ≤ 1000 .
primo
1
Se você considera na entrada mais 9, pode evitar parênteses.
Xnor
@xnor d'oh. Obrigado;)
primo
2
Os primeiros dígitos gerados por esse algoritmo são '3.141596535897932…', que está faltando um '2' entre os pontos 5 e 6. Por que? Porque é quando o operador `` do Python 2 começa a acrescentar um Là string.
Anders Kaseorg
11

Bash + coreutils, 60 49 bytes

echo "scale=10100;4*a(1)"|bc -l|tr -d '\\\n'|cut -c$(($1+2))

bc -l<<<"scale=$1+9;4*a(1)-3"|tr -dc 0-9|cut -c$1

Melhorado por Dennis . Obrigado!

O índice é baseado em um.

Marco
fonte
11

Python 2, 73 71 73 bytes

obrigado a @aditsu por aumentar minha pontuação em 2 bytes

Finalmente, um algoritmo que pode ser concluído em menos de 2 segundos.

n=10**10010
a=p=2*n
i=1
while a:a=a*i/(2*i+1);p+=a;i+=1
lambda n:`p`[n+1]

Ideone it!

Usa a fórmula pi = 4*arctan(1)ao computar arctan(1)usando sua série taylor.

Freira Furada
fonte
Muito rápido. A indexação 1 não é nativa do python. Da última vez que me lembro (é verdade que estou inativo há um tempo), havia consenso de que funções precisam ser definidas, por exemplo f=lambda n:....
primo
2
Quase todas as lambda aqui são anônimas (você pode procurar respostas em Python neste site) #
Leaky Nun
Meta post relevante . Parece estar em violação da Regra 1 e 3 (depois de executar seu código, não há nenhuma maneira de captar a referência de função; a definição da função que precisa ser digitado para cada entrada ( (lambda n:`p`[n+1])(1), (lambda n:`p`[n+1])(2)...).
primo
1
Você não pode executar o código diretamente. É semelhante a colocar importinstruções de antemão, apenas que isso faz algumas variáveis ​​globais de antemão.
Leaky Nun
i=3 while a:a=i/2*a/i;p+=a;i+=2para 4.
primo 04/07
7

MATL, 11 10 bytes

1 byte salvo graças a @Luis

YPiEY$GH+)

Esta solução utiliza indexação baseada em 1

Experimente Online

Todos os casos de teste

Explicação

YP  % Pre-defined literal for pi
iE  % Grab the input and multiply by 2 (to ensure we have enough digits to work with)
Y$  % Compute the first (iE) digits of pi and return as a string
G   % Grab the input again
H+  % Add 2 (to account for '3.') in the string
)   % And get the digit at that location
    % Implicitly display the result
Suever
fonte
@LuisMendo Oh sim, acho que a saída já é uma string. Doh!
Suever 04/07
@LuisMendo Oh, eu nunca pensei nisso. Eu sempre uso YPno meu teste da caixa de ferramentas simbólica
Suever
YP é realmente permitido? A questão diz que é permitido se ele suporta <= 10k dígitos
busukxuan
O @Suever OP declarou "up" em vez de "pelo menos". No meu entender, isso significa que o suporte> 10k é proibido.
busukxuan
@ Suever Sim, eu acho que posso ser, embora eu não resista a fazê-lo lol. Eu apaguei minha resposta do Sage apenas por causa disso.
busukxuan
6

Mathematica 30 bytes

RealDigits[Pi,10,1,-#][[1,1]]&

f=%

f@0
f@1
f@2
f@3
f@10
f@100
f@599
f@760
f@1000
f@10000

1
4
1
5
8
8
2
4
3
5

DavidC
fonte
5

Sábio, 32 25 bytes

lambda d:`n(pi,9^5)`[d+2]

Minha primeira resposta em um idioma desse tipo.

narredonda pipara 17775 dígitos.

busukxuan
fonte
1
Você precisa da printchamada, ou esse é um trecho que só funciona no REPL.
Mego
Isso funciona para (teoricamente) qualquer entrada:lambda d:`n(pi,digits=d+5)`[-4]
Mego
2
@Mego não há execuções "99999"?
Buskxuan
1
@Mego, mas haverá ainda mais "9" execuções. Eu não tenho certeza se a duplicação do comprimento pode torná-lo universal, mas eu não acho que mesmo que pode fazê-lo, devido ao Infinito Macaco Teorema: en.wikipedia.org/wiki/Infinite_monkey_theorem
busukxuan
1
@busukxuan Se você modelar os dígitos não-computados de π como aleatórios, certamente espera que séries arbitrariamente longas de 9s (e não temos motivos para esperar que o real π seja diferente, embora ainda não tenhamos provado isso), mas você só espera um corrida de 9s contanto que sua posição com probabilidade extremamente pequena (embora novamente, não tenhamos provado que o π real não se comporta inesperadamente). Descobrimos séries de pelo menos nove 9s, o que eu acho que é suficiente para quebrar a [-8]proposta.
Anders Kaseorg
4

CJam, 32

7e4,-2%{2+_2/@*\/2e10005+}*sq~)=

Experimente online (é um pouco lento)

aditsu
fonte
4

Mathematica, 23 21 bytes

⌊10^# Pi⌋~Mod~10&

SageMath, 24 bytes

lambda n:int(10^n*pi)%10
Anders Kaseorg
fonte
@LLlAMnYP Eu tentei isso, mas o Mathematica parece exigir um espaço entre Pie (ou entre #e se a multiplicação for invertida), para que a economia desapareça.
Anders Kaseorg
Na verdade, ele funciona no Mathematica Online (eu estava usando a versão do console), então eu aceito, eu acho.
Anders Kaseorg
4
Estas devem ser respostas separadas. Embora eles usem a mesma estratégia, eles não estão nem perto do mesmo idioma.
Mego
@Mego A política que encontrei não diz que as respostas em diferentes idiomas não podem ser consideradas muito semelhantes. (A resposta que sugere que não foi aceita.) Você está se referindo a outra política ou apenas a uma preferência?
Anders Kaseorg
3

J , 19 15 bytes

10([|<.@o.@^)>:

Toma um inteiro n e emite o n th dígitos de pi. Usa indexação baseada em zero. Para obter o n º dígito, pi computação vezes 10 n +1 , use o piso desse valor e, em seguida, o módulo 10.

Uso

A entrada é um número inteiro estendido.

   f =: 10([|<.@o.@^)>:
   (,.f"0) x: 0 1 2 3 10 100 599 760 1000
   0 1
   1 4
   2 1
   3 5
  10 8
 100 8
 599 2
 760 4
1000 3
   timex 'r =: f 10000x'
1100.73
   r
5

Na minha máquina, leva cerca de 18 minutos para calcular os 10000 th dígitos.

Explicação

10([|<.@o.@^)>:  Input: n
             >:  Increment n
10               The constant n
           ^     Compute 10^(n+1)
        o.@      Multiply by pi
     <.@         Floor it
   [             Get 10
    |            Take the floor modulo 10 and return
milhas
fonte
3

Clojure, 312 bytes

(fn[n](let[b bigdec d #(.divide(b %)%2(+ n 4)BigDecimal/ROUND_HALF_UP)m #(.multiply(b %)%2)a #(.add(b %)%2)s #(.subtract % %2)](-(int(nth(str(reduce(fn[z k](a z(m(d 1(.pow(b 16)k))(s(s(s(d 4(a 1(m 8 k)))(d 2(a 4(m 8 k))))(d 1(a 5(m 8 k))))(d 1(a 6(m 8 k)))))))(bigdec 0)(map bigdec(range(inc n)))))(+ n 2)))48)))48)))

Então, como você provavelmente pode perceber, não tenho ideia do que estou fazendo. Isso acabou sendo mais cômico do que qualquer coisa. Coloquei "pi em n dígitos" no Google e acabei no página Wikipedia para a fórmula de Bailey – Borwein – Plouffe . Sabendo Cálculo (?) Apenas o suficiente para ler a fórmula, consegui traduzi-lo para o Clojure.

A tradução em si não foi tão difícil. A dificuldade veio de lidar com precisão até n dígitos, pois a fórmula exige (Math/pow 16 precision); que fica enorme muito rápido. Eu precisava usar em BigDecimaltodos os lugares para que isso funcionasse, o que realmente inchava as coisas.

Ungolfed:

(defn nth-pi-digit [n]
  ; Create some aliases to make it more compact
  (let [b bigdec
        d #(.divide (b %) %2 (+ n 4) BigDecimal/ROUND_HALF_UP)
        m #(.multiply (b %) %2)
        a #(.add (b %) %2)
        s #(.subtract % %2)]
    (- ; Convert the character representation to a number...
      (int ; by casting it using `int` and subtracting 48
         (nth ; Grab the nth character, which is the answer
           (str ; Convert the BigDecimal to a string
             (reduce ; Sum using a reduction
               (fn [sum k]
                 (a sum ; The rest is just the formula
                       (m
                         (d 1 (.pow (b 16) k))
                         (s
                           (s
                             (s
                               (d 4 (a 1 (m 8 k)))
                               (d 2 (a 4 (m 8 k))))
                             (d 1 (a 5 (m 8 k))))
                           (d 1 (a 6 (m 8 k)))))))
               (bigdec 0)
               (map bigdec (range (inc n))))) ; Create an list of BigDecimals to act as k
           (+ n 2)))
      48)))

Escusado será dizer que tenho certeza de que há uma maneira mais fácil de fazer isso, se você conhece alguma matemática.

(for [t [0 1 2 3 10 100 599 760 1000 10000]]
  [t (nth-pi-digit t)])

([0 1] [1 4] [2 1] [3 5] [10 8] [100 8] [599 2] [760 4] [1000 3] [10000 5])
Carcinigenicado
fonte
Percebi mais tarde que os operadores padrão realmente trabalham com grandes decimais, portanto, os atalhos na parte superior são desnecessários. Eu monto corrigir isso em algum momento. Isso provavelmente derrubará ~ 50 bytes.
Carcigenicate
2

Clojure, 253 bytes

(defmacro q[& a] `(with-precision ~@a))(defn h[n](nth(str(reduce +(map #(let[p(+(* n 2)1)a(q p(/ 1M(.pow 16M %)))b(q p(/ 4M(+(* 8 %)1)))c(q p(/ 2M(+(* 8 %)4)))d(q p(/ 1M(+(* 8 %)5)))e(q p(/ 1M(+(* 8 %)6)))](* a(-(-(- b c)d)e)))(range(+ n 9)))))(+ n 2)))

Calcule o número pi usando esta fórmula . É necessário redefinir a macro with-precision, pois é usada com muita frequência.

Você pode ver a saída aqui: https://ideone.com/AzumC3 1000 e 10000 leva excede o limite de tempo usado em ideone, encolhe os ombros

cliffroot
fonte
2

Python 3 , 338 bytes

Essa implementação é baseada no algoritmo de Chudnovsky , um dos algoritmos mais rápidos para estimar pi. Para cada iteração, aproximadamente 14 dígitos são estimados (consulte aqui para mais detalhes).

f=lambda n,k=6,m=1,l=13591409,x=1,i=0:not i and(exec('global d;import decimal as d;d.getcontext().prec=%d'%(n+7))or str(426880*d.Decimal(10005).sqrt()/f(n//14+1,k,m,l,x,1))[n+2])or i<n and d.Decimal(((k**3-16*k)*m//i**3)*(l+545140134))/(x*-262537412640768000)+f(n,k+12,(k**3-16*k)*m

Experimente online!

PieCot
fonte
1

Java 7, 262 260 bytes

import java.math.*;int c(int n){BigInteger p,a=p=BigInteger.TEN.pow(10010).multiply(new BigInteger("2"));for(int i=1;a.compareTo(BigInteger.ZERO)>0;p=p.add(a))a=a.multiply(new BigInteger(i+"")).divide(new BigInteger((2*i+++1)+""));return(p+"").charAt(n+1)-48;}

Utilizado o algoritmo Python 2 do LeakyNun .

Ungolfed & código de teste:

Experimente aqui.

import java.math.*;
class M{
  static int c(int n){
    BigInteger p, a = p = BigInteger.TEN.pow(10010).multiply(new BigInteger("2"));
    for(int i = 1; a.compareTo(BigInteger.ZERO) > 0; p = p.add(a)){
      a = a.multiply(new BigInteger(i+"")).divide(new BigInteger((2 * i++ + 1)+""));
    }
    return (p+"").charAt(n+1) - 48;
  }

  public static void main(String[] a){
    System.out.print(c(0)+", ");
    System.out.print(c(1)+", ");
    System.out.print(c(2)+", ");
    System.out.print(c(3)+", ");
    System.out.print(c(10)+", ");
    System.out.print(c(100)+", ");
    System.out.print(c(599)+", ");
    System.out.print(c(760)+", ");
    System.out.print(c(1000)+", ");
    System.out.print(c(10000));
  }
}

Saída:

1, 4, 1, 5, 8, 8, 2, 4, 3, 5
Kevin Cruijssen
fonte
1

Smalltalk - 270 bytes

Confia na identidade tan⁻¹(x) = x − x³/3 + x⁵/5 − x⁷/7 ..., e isso π = 16⋅tan⁻¹(1/5) − 4⋅tan⁻¹(1/239). O SmallTalk usa aritmética inteira de precisão ilimitada, de modo que funcionará para entradas grandes, se você estiver disposto a esperar!

|l a b c d e f g h p t|l:=stdin nextLine asInteger+1. a:=1/5. b:=1/239. c:=a. d:=b. e:=a. f:=b. g:=3. h:=-1. l timesRepeat:[c:=c*a*a. d:=d*b*b. e:=h*c/g+e. f:=h*d/g+f. g:=g+2. h:=0-h]. p:=4*e-f*4. l timesRepeat:[t:=p floor. p:=(p-t)*10]. Transcript show:t printString;cr

Salve como pi.ste execute como nos seguintes casos de teste. A indexação é baseada.

$ gst -q pi.st <<< 1
1
$ gst -q pi.st <<< 2
4
$ gst -q pi.st <<< 3
1
$ gst -q pi.st <<< 4
5
$ gst -q pi.st <<< 11
8
$ gst -q pi.st <<< 101
8
$ gst -q pi.st <<< 600
2
$ gst -q pi.st <<< 761
4
$ gst -q pi.st <<< 1001
3
$ gst -q pi.st <<< 10001 -- wait a long time!
5

fonte
1

JavaScript (Node.js) (Chrome 67+), 75 73 67 63 bytes

n=>`${eval(`for(a=c=100n**++n*20n,d=1n;a*=d;)c+=a/=d+++d`)}`[n]

Experimente online!

Usando π/2=k=0 0k!/(2k+1)!!(mesma lógica usada pela resposta Python de Leaky Nun, mas graças à sintaxe de JS que torna isso mais curto). A entrada é passada para a função como um BigInt. 2 bytes podem ser removidos se a indexação baseada em 1 for usada:

n=>`${eval(`for(a=c=100n**n*20n,d=1n;a*=d;)c+=a/=d+++d`)}`[n]

JavaScript (Node.js) (Chrome 67 ou superior), 90 89 bytes

n=>`${eval(`for(a=100n**++n*2n,b=a-a/3n,c=0n,d=1n;w=a+b;a/=-4n,b/=-9n,d+=2n)c+=w/d`)}`[n]

Experimente online!

Usando π/4=arctan(1/2)+arctan(1/3). A entrada é passada para a função como um BigInt. 2 bytes podem ser removidos se a indexação baseada em 1 for usada:

n=>`${eval(`for(a=100n**n*2n,b=a-a/3n,c=0n,d=1n;w=a+b;a/=-4n,b/=-9n,d+=2n)c+=w/d`)}`[n]
Shieru Asakoto
fonte
0

Bordo, 24 bytes

 trunc(10^(n+1)*Pi)mod 10

Casos de teste:

> f:=n->trunc(10^(n+1)*Pi)mod 10;
> f(0);
  1
> f(1);
  4
> f(2);
  1
> f(3);
  5
> f(10);
  8
> f(100);
  8
> f(599);
  2
> f(760);
  4
> f(1000);
  3
> f(10000);
  5
DSkoog
fonte
0

C #, 252 250 bytes

d=>{int l=(d+=2)*10/3+2,j=0,i=0;long[]x=new long[l],r=new long[l];for(;j<l;)x[j++]=20;long c,n,e,p=0;for(;i<d;++i){for(j=0,c=0;j<l;c=x[j++]/e*n){n=l-j-1;e=n*2+1;r[j]=(x[j]+=c)%e;}p=x[--l]/10;r[l]=x[l++]%10;for(j=0;j<l;)x[j]=r[j++]*10;}return p%10+1;}

Experimente online!

TheLethalCoder
fonte