Números pirracionais

14

Pi é um número irracional , o que significa que sua representação decimal nunca termina ou se repete.

Pi truncado com 41 dígitos decimais (40 casas) é 3.1415926535897932384626433832795028841971.

Se ignorarmos o ponto decimal e listar os dígitos como uma sequência de números inteiros positivos, evitando duplicatas , obteremos 3 1 4 15 9 2 6 5 35 8 97 93 23 84 62 64 33 83 27 950 28 841 971( OEIS A064809 ).
(Observe que 15aparece na sequência em vez de 1 5porque 1já havia ocorrido.
Observe também que 0não ocorre porque não é positivo; 950contém o primeiro zero.)

Para construir o primeiro número pirracional , usamos essa sequência para indexar os dígitos do Pi (o primeiro dígito é 3, o segundo 1 etc.).

Portanto, o primeiro dígito do primeiro número pirracional é o terceiro dígito do Pi,
o segundo dígito é o 1º dígito do Pi,
o terceiro dígito é o 4º dígito do Pi,
o quarto é o 15º dígito do Pi,
e assim por diante.
Um ponto decimal é adicionado após o primeiro dígito para imitar Pi.

Assim, o primeiro número pirracional com 41 dígitos é 4.3195195867462520687356193644029372991880.
(Observe que, para o 30º dígito, tive que percorrer todo o caminho até o 974º dígito do Pi.)

Para construir o segundo número pirracional, o processo é repetido usando o primeiro número pirracional em vez de Pi. (O próprio Pi pode ser chamado de número pirracional zero.) Portanto, a nova sequência é 4 3 1 9 5 19 58 ...e o primeiro número piiracional é indexado para produzir o segundo, que inicia 9.14858....

Outros números pirracionais são criados da mesma maneira, cada um sendo gerado a partir do número anterior.

Desafio

Sua tarefa é escrever o programa mais curto possível, que recebe dois números inteiros, Ne D, e gera o Nnúmero pirracional truncado para Ddígitos decimais.

Dé sempre positivo, mas Nnão negativo, e os Ddígitos de Pi devem ser impressos quando Né 0.
Quando Dé 1, não importa se o ponto decimal está presente ou não.

A entrada deve vir de stdin ou a linha de comando e a saída deve ir para stdout (ou as alternativas mais próximas do seu idioma).

Seu programa deve funcionar para todos os valores de entrada iguais Nou Dinferiores a 2 16 , mas não precisa ser oportuno ou eficiente.

O código mais curto em bytes vence.

(Observe que os números pirracionais existem em outras bases, mas tudo neste desafio é feito na base 10.)

Passatempos de Calvin
fonte
Podemos usar representações de precisão arbitrária do Pi para obter seus dígitos?
Martin Ender
1
@ MartinBüttner Claro. Você pode até obter os dígitos de pi on-line se quiser, desde que você esteja obtendo apenas os dígitos de pi.
Passatempos de Calvin
@ Calvin'sHobbies: Ah legal, então eu posso ter os primeiros 64ki dígitos de pi em um arquivo? Devo adicionar +1 ao nome do arquivo?
Claudiu 24/09
Esse intervalo de entrada está correto? Para N=1, D=13393por exemplo, você precisaria o dígito 31 milionésimo de PI
Claudiu
Os primeiros 1 bilhão de dígitos do pi só você fica 42,598 dígitos do 1º número pirrational
Claudiu

Respostas:

3

Python 292 bytes

Bastante ineficiente, só consegui obter alguns dígitos de N = 3 e nenhum de N = 4.

import sympy
def P(N,D,s=''):
 if N<1:return'3'+`sympy.pi.evalf(D+9)`[2:-9]
 for i in range(D):
    h=[];l='';j=i;x=0
    while-~j:
     x+=1;d=P(N-1,x)[-1];l+=d
     while'1'>P(N-1,x+1)[-1]:x+=1;l+='0'
     if(l in h)<1:h+=[l];l='';j-=1
    s+=P(N-1,int(h[i]))[-1]
 return s
s=P(*input())
print s[0]+'.'+s[1:]

Entrada de amostra:

0,20
3.1415926535897932384

1,20
4.3195195867462520687

2,10
9.148583196

3,5
9.9815
KSab
fonte
Golfe: mude =="0"para <"1". Faça o loop while interno uma linha. Remova espaços ao redor x += 1. if l not in h-> if(l in h)<1: N==0->N<1
isaacg
@isaacg Obrigado por isso, eu estava com pressa quando publiquei e perdi algumas coisas óbvias. Eu provavelmente não teria percebido que você poderia fazer a comparação de strings e isso if(l in h)<1também é bastante inteligente.
KSab
Um pouco mais: Inicialize scomo um parâmetro de P( def P(N,D,s=''):). str(...)provavelmente pode ser escrito com backticks. while'1'>...economiza o espaço. Faça hum conjunto e inicialize com h=l,={''}, depois escreva l in hcomo {l}<h.
Flornquake #
@flornquake Isso é bastante inteligente, especialmente a maneira como você o inicializa, para que o python não pense que é um ditado. Enquanto eu colocava isso, percebi uma otimização bastante grande que infelizmente precisava hser solicitada. Ainda assim, é um truque interessante que vou tentar lembrar.
KSab # 24/14
@KSab Isso é ainda melhor. :) while j+1:pode ser encurtado para while-~j, btw.
flornquake
4

Haskell, 431 400 369

import Data.List
g(q,r,t,k,n,l)|4*q+r-t<n*t=n:g(q#0,(r-n*t)#0,t,k,div(r#(30*q))t-n#0,l)|1<2=g(q*k,(2*q+r)*l,t*l,k+1,div(q*(7*k+2)+r*l)(t*l),l+2)
u w@(x:y:xs)=x:v y xs 0 w
v a(r:s)n w|a`elem`take n(u w)||r==0=v(a#r)s n w|1<2=a:v r s(n+1)w
m p=map(genericIndex p.pred)$u p
a#b=a*10+b
(x:s)%n=show x++'.':show(foldl1(#)$n`take`s)
f n d=print$iterate m(g(1,0,1,1,3,3))!!n%d

Conseguiu amar listas infinitas! Com tempo e memória suficientes, este programa acabará por calcular a resposta certa para qualquer N e D (presumo).

Estou gerando os dígitos do pi gusando um algoritmo de torneira (roubado descaradamente de um cara chamado Stanley Rabinowitz), agrupando os dígitos / criando a sequência usando ve gerando um número pirracional a partir deles m.

Aqui está em ação:

λ> f 0 10
"3.1415926535"
λ> f 1 10
"4.3195195867"
λ> f 2 10
"9.Interrupted. --didn't have the time to wait for this to finish
λ> f 2 4
"9.1485"
Flonk
fonte
1
Eu pensei "Haskell!" quando vi a pergunta, rolei para baixo e sorri.
Soham Chowdhury