Su objetivo es generar la secuencia estrictamente creciente de dígitos consecutivos e idénticos de pi (π). Cada término en la secuencia debe ser un dígito más largo que el anterior. Entonces 3
(0º dígito de pi) es la primera vez que ocurre una serie de dígitos (longitud 1). El siguiente en ocurrir es 33
(dígitos 24 y 25 de pi). Por supuesto, esta secuencia requiere que los dígitos de pi estén en la base 10 .
Los conocidos hasta ahora , y los primeros seis, todos ocurren dentro de los primeros 800 dígitos:
3
33
111
9999
99999
999999
3333333
44444444
777777777
6666666666
... (not in first 2 billion digits)
Tenga en cuenta que los nueve consecutivos ocurren todos juntos, en la misma ejecución, por lo que si la próxima ejecución más grande que encontró son 1000 0
s consecutivos , esto llenaría múltiples términos de la secuencia.
No he encontrado más términos con mi programa. Sé que no hay más términos dentro de los primeros 50000 dígitos o más. Mi programa estaba tardando demasiado con 500000 dígitos, así que me di por vencido.
Puedes:
- Salida de la secuencia para siempre
- Toma un número entero
n
y encuentra los primerosn
números en la secuencia - Tome un número entero
n
y encuentre los números en la secuencia contenida en los primerosn
dígitos de pi.
Asegúrese de especificar cuál hace su código. El número n
puede ser cero o uno indexado.
Inspirado por esta pregunta de mathoverflow .
Respuestas:
Mathematica, 85 bytes
Función anónima. Toma n como entrada y devuelve los elementos de la secuencia en los primeros n dígitos de π. La salida es en forma de
{0, 3, 33, 111, ...}
.fuente
Python 2, 110 bytes
El número máximo de dígitos para verificar se toma de stdin. 10,000 dígitos terminan en aproximadamente 2 segundos con PyPy 5.3.
Uso de muestra
Algo útil
He cambiado de Chudnovsky a Ramanujan 39 por esto. Chudnovsky se quedó sin memoria en mi sistema poco después de 100 millones de dígitos, pero Ramanujan llegó a 400 millones, en solo unos 38 minutos. Creo que este es otro caso en el que la tasa de crecimiento de términos más lenta gana al final, al menos en un sistema con recursos limitados.
Uso de muestra
Generadores ilimitados más rápidos
La implementación de referencia dada en la descripción del problema es interesante. Utiliza un generador ilimitado, tomado directamente del papel Algoritmos de espiga no limitada para los dígitos de Pi . Según el autor, las implementaciones proporcionadas son "deliberadamente oscuras", por lo que decidí hacer nuevas implementaciones de los tres algoritmos enumerados por el autor, sin ofuscación deliberada. También agregué un cuarto, basado en Ramanujan # 39 .
Notas
Arriba hay 6 implementaciones: las dos implementaciones de referencia proporcionadas por el autor (denotado
_ref
), y cuatro que calculan términos en lotes, generando múltiples dígitos a la vez (_md
). Todas las implementaciones han sido confirmadas a 100,000 dígitos. Al elegir tamaños de lote, elegí valores que lentamente pierden precisión con el tiempo. Por ejemplo,g1_md
genera 10 dígitos por lote, con 33 iteraciones. Sin embargo, esto solo producirá ~ 9.93 dígitos correctos. Cuando se agote la precisión, la condición de verificación fallará, lo que desencadenará la ejecución de un lote adicional. Esto parece ser más eficaz que la precisión lenta y adicionalmente innecesaria con el tiempo.Se
j
mantiene una variable adicional que representa2*i+1
. El autor hace lo mismo en la implementación de referencia. Calcular porn
separado es mucho más simple (y menos oscuro), porque utiliza los valores actuales deq
,r
yt
, en lugar de los siguientes.El cheque
n == q/s
es ciertamente bastante laxo. Eso debería leern == (q*(k+2*j+4)+r)/(s*(k+2*j+4)+t)
, dóndej
está2*i-1
yk
estái*i
. En iteraciones más altas, los términosr
y set
vuelven cada vez menos significativos. Como es, es bueno para los primeros 100,000 dígitos, por lo que probablemente sea bueno para todos. El autor no proporciona implementación de referencia.El autor conjetura que no es necesario verificar que
n
no cambiará en las iteraciones posteriores, y que solo sirve para ralentizar el algoritmo. Aunque probablemente sea cierto, el generador está reteniendo ~ 13% más dígitos correctos de los que ha generado actualmente, lo que parece un poco inútil. He agregado el cheque nuevamente y espero hasta que 50 dígitos sean correctos, generándolos todos a la vez, con una ganancia notable en el rendimiento.Calculado como
Desafortunadamente,
s
no se pone a cero, debido a la composición inicial (3528 ÷), pero sigue siendo significativamente más rápido que g3. La convergencia es de ~ 5.89 dígitos por término, se generan 3511 dígitos a la vez. Si eso es demasiado, generar 271 dígitos por 46 iteraciones también es una opción decente.Tiempos
Tomado en mi sistema, solo para fines de comparación. Los tiempos se enumeran en segundos. Si un tiempo tardó más de 10 minutos, no ejecuté más pruebas.
Es interesante que
g2
finalmente supereg3
, a pesar de una tasa de convergencia más lenta. Sospecho que esto se debe a que los operandos crecen a un ritmo significativamente más lento, ganando a la larga. La implicación más rápidag4_md
es aproximadamente 235 veces más rápida que lag3_ref
implicación en 500,000 dígitos. Dicho esto, todavía hay una sobrecarga significativa para la transmisión de dígitos de esta manera. Calcular todos los dígitos directamente usando Ramanujan 39 ( fuente de Python ) es aproximadamente 10 veces más rápido.¿Por qué no Chudnovsky?
El algoritmo de Chudnovsky requiere una raíz cuadrada de precisión completa, que honestamente no estoy seguro de cómo trabajar, suponiendo que pueda serlo. Ramanujan 39 es algo especial en este sentido. Sin embargo, parece que el método podría conducir a fórmulas similares a las de Machin, como las utilizadas por y-cruncher, por lo que podría ser una vía que vale la pena explorar.
fuente
Haskell, 231 bytes
Utiliza los algoritmos de espiga ilimitada para los dígitos de Pi de Jeremy Gibbons, 2004. El resultado es
p
. Técnicamente, debería admitir secuencias de salida infinitas, pero eso puede llevar un tiempo (y está limitado por su memoria).fuente
Python 2, 298 bytes
Tenga en cuenta que el código para generar pi se toma de la implementación del OP.
Mi primer intento de jugar golf en Python. Emite la secuencia para siempre.
fuente
π
aquí? Usted, por supuesto, calcula pi, ¿verdad?π
para siempre allí?yield
que lo detiene, pero no soy muy bueno en pythonp
partePython 3.5,
278263 bytes:Esto toma
n
como entrada para los primerosn
dígitos deπ
y luego genera los miembros de la secuencia en esos primerosn
dígitos. Ahora, esto usa el módulo decimal incorporado de Python para ir más allá de las limitaciones de punto flotante de Python, y luego establece la precisión, o épsilon, a la cantidad de entradas del usuario. Luego, para calcularπ
, esto pasa por 50 iteraciones usando el eficiente algoritmo Gausse-Legendre , ya que el algoritmo aparentemente duplica el número de dígitos correctos cada vez, y por lo tanto, en 50 iteraciones, podemos obtener2^50
o1,125,899,906,842,624
corregir dígitos. Finalmente, después de realizar los cálculos, utiliza una expresión regular con formato de cadena en unwhile
bucle para buscar e imprimirre
emparejar objetos (que espero que esté bien) para todos los dígitos continuos y recurrentes 1 dígito más que en la iteración anterior a través del bucle.Pude usar este algoritmo para calcular con éxito y precisión
π
hasta10,000,000
(diez millones) dígitos, lo que tardó aproximadamente 4 horas y 12 minutos en completarse. El siguiente fue el resultado final:¡Entonces, puedo decir con confianza que el octavo número en la secuencia ni siquiera aparece dentro de los primeros 10 millones de dígitos!
π
es un número aleatorio ...fuente