Seu objetivo é produzir a sequência estritamente crescente de dígitos consecutivos idênticos de pi (π). Cada termo na sequência deve ter um dígito a mais que o anterior. Então 3
(0º dígito de pi) é a primeira vez que ocorre uma sequência de dígitos (comprimento 1). O próximo a ocorrer é 33
(dígitos 24 e 25 de pi). Obviamente, essa sequência requer que os dígitos de pi estejam na base 10 .
Os conhecidos até agora e os seis primeiros ocorrem nos primeiros 800 dígitos:
3
33
111
9999
99999
999999
3333333
44444444
777777777
6666666666
... (not in first 2 billion digits)
Observe que todos os nove consecutivos ocorrem juntos, na mesma execução, portanto, se a próxima execução maior que você encontrou fosse 1000 0
s consecutivos , isso preencheria vários termos da sequência.
Não encontrei mais termos com o meu programa. Sei que não há mais termos nos primeiros 50000 dígitos ou mais. Meu programa estava demorando muito com 500000 dígitos, então desisti.
Você pode:
- Saída da sequência para sempre
- Pegue um número inteiro
n
e encontre os primeirosn
números na sequência - Pegue um número inteiro
n
e encontre os números na sequência contida nos primeirosn
dígitos de pi.
Certifique-se de especificar qual é o seu código. O número n
pode ser zero ou um indexado.
Inspirado por esta pergunta do mathoverflow .
Respostas:
Mathematica, 85 bytes
Função anônima. Pega n como entrada e retorna os elementos da sequência nos primeiros n dígitos de π. A saída está na forma de
{0, 3, 33, 111, ...}
.fonte
Python 2, 110 bytes
O número máximo de dígitos a serem verificados é obtido a partir do stdin. 10.000 dígitos terminam em cerca de 2s com o PyPy 5.3.
Uso da amostra
Algo util
Eu mudei de Chudnovsky para Ramanujan 39 para isso. Chudnovsky ficou sem memória no meu sistema logo após 100 milhões de dígitos, mas Ramanujan chegou a 400 milhões, em apenas 38 minutos. Acho que esse é outro caso em que a taxa de crescimento mais lenta dos termos vence no final, pelo menos em um sistema com recursos limitados.
Uso da amostra
Geradores não ligados mais rápidos
A implementação de referência dada na descrição do problema é interessante. Ele usa um gerador ilimitado, extraído diretamente do algoritmo de torneira não encadernada para os dígitos do Pi . Segundo o autor, as implementações fornecidas são "deliberadamente obscuras", por isso decidi fazer novas implementações dos três algoritmos listados pelo autor, sem ofuscação deliberada. Eu também adicionei um quarto, baseado no Ramanujan # 39 .
Notas
Acima estão 6 implementações: as duas implementações de referência fornecidas pelo autor (denotadas
_ref
) e quatro que computam termos em lotes, gerando vários dígitos ao mesmo tempo (_md
). Todas as implementações foram confirmadas para 100.000 dígitos. Ao escolher tamanhos de lote, escolhi valores que lentamente perdem a precisão ao longo do tempo. Por exemplo,g1_md
gera 10 dígitos por lote, com 33 iterações. No entanto, isso produzirá apenas ~ 9,93 dígitos corretos. Quando a precisão acabar, a condição de verificação falhará, acionando um lote extra a ser executado. Isso parece ser mais eficiente do que a precisão desnecessariamente desnecessária e desnecessária ao longo do tempo.Uma variável extra
j
é mantida, representando2*i+1
. O autor faz o mesmo na implementação de referência. Calcularn
separadamente é muito mais simples (e menos obscuro), porque usa os valores atuais deq
,r
et
, em vez do seguinte.O cheque
n == q/s
é reconhecidamente bastante relaxado. Isso deve lern == (q*(k+2*j+4)+r)/(s*(k+2*j+4)+t)
, ondej
está2*i-1
ek
estái*i
. Em iterações mais altas, os termosr
et
se tornam cada vez menos significativos. Como é, é bom para os primeiros 100.000 dígitos, então provavelmente é bom para todos. O autor não fornece nenhuma implementação de referência.O autor conjectura que não é necessário verificar se isso
n
não será alterado nas iterações subseqüentes e que serve apenas para retardar o algoritmo. Embora provavelmente seja verdade, o gerador está mantendo ~ 13% mais dígitos corretos do que o gerado atualmente, o que parece um pouco inútil. Adicionei o check-in novamente e aguarde até 50 dígitos estarem corretos, gerando todos de uma só vez, com um ganho notável no desempenho.Calculado como
Infelizmente,
s
não é zerado, devido à composição inicial (3528 ÷), mas ainda é significativamente mais rápido que o g3. A convergência é de ~ 5,89 dígitos por termo, 3511 dígitos são gerados por vez. Se isso é um pouco demais, gerar 271 dígitos por 46 iterações também é uma escolha decente.Horários
Tirada no meu sistema, apenas para fins de comparação. Os horários são listados em segundos. Se um tempo demorasse mais de 10 minutos, não executei mais testes.
É interessante que,
g2
eventualmenteg3
, supere , apesar de uma taxa mais lenta de convergência. Suspeito que isso ocorra porque os operandos crescem a uma taxa significativamente mais lenta, vencendo a longo prazo. A implementação mais rápidag4_md
é aproximadamente 235x mais rápida que ag3_ref
implementação em 500.000 dígitos. Dito isto, ainda há uma sobrecarga significativa para a transmissão de dígitos dessa maneira. O cálculo de todos os dígitos diretamente usando o Ramanujan 39 ( fonte python ) é aproximadamente 10 vezes mais rápido.Por que não Chudnovsky?
O algoritmo de Chudnovsky requer uma raiz quadrada de precisão total, na qual sinceramente não sei como trabalhar - assumindo que possa ser. Ramanujan 39 é um tanto especial nesse sentido. No entanto, o método parece propício a fórmulas do tipo Machin, como as usadas pelo triturador de y, de modo que pode ser uma avenida que vale a pena explorar.
fonte
Haskell, 231 bytes
Isso usa os algoritmos de espigão ilimitado para os dígitos do Pi de Jeremy Gibbons, 2004. O resultado é
p
. Tecnicamente, ele deve suportar infinitas seqüências de saída, mas isso pode demorar um pouco (e é limitado pela sua memória).fonte
Python 2, 298 bytes
Observe que o código para gerar pi é obtido da implementação do OP.
Minha primeira tentativa de jogar golfe em Python. Produz a sequência para sempre.
fonte
π
aqui? Você, é claro, calcula pi, certo?π
para sempre?yield
que pára-lo, mas eu não sou muito bom em pythonp
partePython 3.5,
278263 bytes:Isso recebe
n
como entrada os primeirosn
dígitos deπ
e, em seguida, gera os membros da sequência nesses primeirosn
dígitos. Agora, isso usa o módulo decimal embutido do Python para ir além das limitações de ponto flutuante do Python e, em seguida, define a precisão, ou epsilon, para o quanto as entradas do usuário. Então, para calcularπ
, isso passa por 50 iterações usando o eficiente algoritmo de Gausse-Legendre , já que o algoritmo aparentemente dobra o número de dígitos corretos a cada vez e, portanto, em 50 iterações, podemos obter2^50
ou1,125,899,906,842,624
corrigir dígitos. Finalmente, após os cálculos, ele usa uma expressão regular com formatação de string em umwhile
loop para encontrar e imprimirre
objetos de correspondência (que espero que estejam bem) para todos os dígitos recorrentes e contínuos 1 dígito a mais do que na iteração anterior através do loop.Consegui usar esse algoritmo para calcular com êxito e precisão
π
até10,000,000
(dez milhões) dígitos, o que levou cerca de 4 horas e 12 minutos para ser concluído. O seguinte foi a saída final:Então, posso dizer com confiança que o 8º número da sequência nem ocorre nos primeiros 10 milhões de dígitos!
π
é um número aleatório ...fonte