Números pirracionales

14

Pi es un número irracional , lo que significa que su representación decimal nunca termina o se repite.

Pi truncado a 41 dígitos decimales (40 lugares) es 3.1415926535897932384626433832795028841971.

Si ignoramos el punto decimal y enumeramos los dígitos como una secuencia de enteros positivos, evitando duplicados , obtenemos 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 en la secuencia en lugar de 1 5porque 1ya había ocurrido.
También tenga en cuenta que 0no ocurre porque no es positivo; 950contiene el primer cero).

Para construir el primer número pirracional , usamos esta secuencia para indexar los dígitos de Pi (el primer dígito es 3, el segundo 1, etc.).

Entonces, el primer dígito del primer número pirracional es el tercer dígito de Pi,
el segundo dígito es el primer dígito de Pi,
el tercer dígito es el cuarto dígito de Pi,
el cuarto es el décimo quinto dígito de Pi,
y así sucesivamente.
Se agrega un punto decimal después del primer dígito para imitar Pi.

Así, el primer número pirracional de 41 dígitos es 4.3195195867462520687356193644029372991880.
(Tenga en cuenta que para el 30º dígito tuve que ir hasta el 974º dígito de Pi).

Para construir el segundo número pirracional, el proceso se repite utilizando el primer número pirracional en lugar de Pi. (Pi mismo puede llamarse el número pirracional cero). Entonces, la nueva secuencia es 4 3 1 9 5 19 58 ...y el primer número piracional se indexa para producir el segundo, que comienza 9.14858....

Otros números pirracionales se crean de la misma manera, cada uno generado a partir del anterior.

Desafío

Su tarea consiste en escribir el programa más corto posible que se lleva en dos enteros, Ny D, y emite el Nnúmero pirrational º truncada de Ddígitos decimales.

Dsiempre es positivo, pero Nno es negativo, y los Ddígitos de Pi deben salir cuando Nes 0.
Cuando Des 1, no importa si el punto decimal está presente o no.

La entrada debe provenir de stdin o la línea de comando y la salida debe ir a stdout (o las alternativas más cercanas a su idioma).

Su programa debería funcionar para todos los valores de entrada de Ny Dpor debajo de 2 16 , pero no necesita ser oportuno o eficiente.

El código más corto en bytes gana.

(Tenga en cuenta que los números pirracionales existen en otras bases, pero todo en este desafío se hace en la base 10.)

Pasatiempos de Calvin
fuente
¿Podemos usar representaciones de precisión arbitraria incorporadas de Pi para obtener sus dígitos?
Martin Ender
1
@ MartinBüttner Claro. Incluso puede obtener los dígitos de Pi en línea si lo desea, siempre y cuando solo obtenga los dígitos de Pi.
Aficiones de Calvin
@ Calvin'sHobbies: Ah, bien, ¿puedo tener los primeros 64ki dígitos de pi en un archivo? ¿Debo agregar +1 para el nombre del archivo?
Claudiu
¿Es correcto ese rango de entrada? Para N=1, D=13393por ejemplo, se necesitaría el dígito 31000000o de PI
Claudiu
Los primeros mil millones de dígitos de pi solo te dan 42,598 dígitos del primer número pirracional
Claudiu

Respuestas:

3

Python 292 bytes

Muy ineficiente, solo he podido obtener unos pocos dígitos de N = 3 y ninguno 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 muestra:

0,20
3.1415926535897932384

1,20
4.3195195867462520687

2,10
9.148583196

3,5
9.9815
KSab
fuente
Golfs: Cambiar =="0"a <"1". Haga el interior mientras bucle una línea. Eliminar espacios alrededor x += 1. if l not in h-> if(l in h)<1: N==0->N<1
isaacg
@isaacg Gracias por eso, tenía un poco de prisa cuando publiqué y me perdí algunas cosas obvias. Sin embargo, probablemente no me habría dado cuenta de que podría hacer la comparación de cadenas y if(l in h)<1también es bastante inteligente.
KSab
Un poco más: Inicializar scomo un parámetro de P( def P(N,D,s=''):). str(...)probablemente se puede escribir con backticks. while'1'>...ahorra el espacio Haga hun conjunto e inicialice con h=l,={''}, luego escriba l in hcomo {l}<h.
flornquake
@flornquake Eso es bastante inteligente, especialmente la forma en que lo inicializa para que Python no piense que es un dict. Sin embargo, cuando estaba poniendo esto, me di cuenta de una optimización bastante grande que desafortunadamente requería hser ordenada. Aún así, ese es un buen truco que intentaré recordar.
KSab
@KSab Eso es aún mejor. :) while j+1:se puede acortar a while-~j, por cierto.
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

¡Tengo que amar listas infinitas! Dado suficiente tiempo y memoria, este programa eventualmente calculará la respuesta correcta para cualquier N y D (supongo).

Estoy generando los dígitos de pi gusando un algoritmo de espita (descaradamente robado de un tipo llamado Stanley Rabinowitz), agrupando los dígitos / creando la secuencia usando vy generando un número pirracional a partir de estos usando m.

Aquí está en acción:

λ> 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
fuente
1
Pensé "Haskell!" cuando vi la pregunta, me desplacé hacia abajo y sonreí.
Soham Chowdhury