Fila de números naturales

22

Definición

Hay una fila infinita de números naturales concatenados (enteros positivos, que comienzan con 1):

1234567891011121314151617181920212223...

Reto

  • Escriba el programa en cualquier idioma, que acepte el número de posición como entrada, y genere dígitos desde esa posición en la fila definida anteriormente.
  • El número de posición es un entero positivo de tamaño arbitrario. Esa es la primera posición es 1, produciendo el dígito de salida '1'
  • La entrada está en decimal (por ejemplo, 13498573249827349823740000191) o en notación electrónica (por ejemplo, 1.2e789) correspondiente a un entero positivo.
  • El programa debe finalizar en un tiempo razonable (10 segundos en una PC / Mac moderna), dado un índice muy grande como entrada (por ejemplo, 1e123456, es decir, 1 con 123456 ceros). Por lo tanto, el bucle de iteración simple no es aceptable.
  • El programa tiene que terminar con un error en 1 s, si se le da alguna entrada no válida. P.ej. 1.23e (inválido), o 1.23e1 (igual a 12.3 - no es un número entero)
  • Está bien usar la biblioteca pública BigNum para analizar / almacenar números y realizar operaciones matemáticas simples en ellos (+ - * / exp). No se aplica penalización por byte.
  • El código más corto gana.

TL; DR

  • Entrada: entero bignum
  • Salida: dígito en esa posición en fila infinita 123456789101112131415...

Algunos casos de prueba de aceptación

en notación "Entrada: Salida". Todos deberían pasar.

  • 1: 1
  • 999: 9
  • 10000000: 7
  • 1e7: 7 (igual que la fila de arriba)
  • 13498573249827349823740000191: 6
  • 1.1e10001: 5
  • 1e23456: 5
  • 1.23456e123456: 4
  • 1e1000000: 0
  • 1.23e: error (sintaxis no válida)
  • 0: error (fuera de límites)
  • 1.23e1: error (no es un número entero)

¡Prima!

Número de posición del dígito de salida dentro del número, y el número de salida en sí. Por ejemplo:

  • 13498573249827349823740000191: 6 24 504062383738461516105596714
    • Eso de dígitos '6' en la posición 24 de la serie '50406238373846151610559 6 714'
  • 1e1000000: 0 61111 1000006111141666819445...933335777790000
    • Dígito '0' en la posición 61111 del número largo de 999995 dígitos que no voy a incluir aquí.

Si cumple la tarea de bonificación, multiplique el tamaño de su código por 0.75

Crédito

Esta tarea se dio en una de las reuniones de devclub.eu en el año 2012, sin un gran número de requisitos. Por lo tanto, la mayoría de las respuestas enviadas fueron bucles triviales.

¡Que te diviertas!

metalim
fuente
Realmente no entiendo cuál es el desafío. ¿Se supone que debemos tomar la entrada y la salida del número en esa posición?
The_Basset_Hound
1
Esta es la secuencia OEIS 33307 .
Tyilo
2
@vihan Usar alguna biblioteca pública de bignum es aceptable. Ninguna penalización. Por supuesto, incluir la solución en la biblioteca y usar la biblioteca de una sola línea está considerando hacer trampa. El sentido común se aplica aquí.
metalim
1
Solo quería mostrar una solución F # sorprendentemente concisa , registrando 44 bytes. Por supuesto, solo puede manejar índices de hasta 2 ^ 31-1 (y todavía está tratando de calcular ese valor mientras escribo esto). Sin embargo, no estoy publicando esto porque realmente rompe las reglas, ¡pero diría que es bastante bueno para F #!
Jwosty
77
Los requisitos para manejar entradas como 1.23456e123456castigan arbitrariamente los lenguajes que no pueden procesar dichos valores de forma nativa y requieren que realicen un procesamiento de cadena que sea tangencial al desafío.
xnor

Respuestas:

12

CJam , 78 bytes

r_A,s-" e . .e"S/\a#[SSS"'./~'e/~i1$,-'e\]s"0]=~~_i:Q\Q=Qg&/
s,:L{;QAL(:L#9L*(*)9/-_1<}g(L)md_)p\AL#+_ps=

El programa tiene 104 bytes de largo y califica para el bono.

La nueva línea es puramente cosmética. La primera línea analiza la entrada, la segunda genera la salida.

Pruébalo en línea!

Idea

Para cualquier entero positivo k , hay 9 × 10 k-1 enteros positivos de exactamente k dígitos (sin contar los ceros a la izquierda). Por lo tanto, si los concatenamos todos, obtenemos un número entero de 9 × n × 10 k-1 .

Ahora, la concatenación de todos los enteros de n o menos dígitos produce un entero de

fórmula

dígitos

Para una entrada dada q , tratamos de determinar la n más alta de manera que la expresión anterior sea menor que q . Establecemos n: = ⌈log 10 q⌉-1 , luego n: = ⌈log 10 q⌉-2 , etc. hasta que la expresión deseada sea más pequeña que q , reste la expresión resultante de q (produciendo r ) y guarde el último valor de n en l .

r ahora especifica el índice en la concatenación de todos los enteros positivos de l + 1 dígitos, lo que significa que la salida deseada es el r% (l + 1) th dígito del r / (l + 1) th entero de l + 1 dígitos

Código (análisis de entrada)

r_          e# Read from STDIN and duplicate.
A,s-        e# Remove all digits.
" e . .e"S/ e# Push ["" "e" "." ".e"].
\a#         e# Compute the index of the non-digit part in this array.

[SSS"'./~'e/~i1$,-'e\]s"0]

            e# Each element corresponds to a form of input parsing:
            e#   0 (only digits): noop
            e#   1 (digits and one 'e'): noop
            e#   2 (digits and one '.'): noop
            e#   3 (digits, one '.' then one 'e'):
            e#     './~    Split at dots and dump the chunks on the stack.
            e#     'e/~    Split the and chunks at e's and dump.
            e#     i       Cast the last chunk (exponent) to integer.
            e#     1$      Copy the chunk between '.' and 'e' (fractional part).
            e#     ,-      Subtract its length from the exponent.
            e#     'e\     Place an 'e' between fractional part and exponent.
            e#     ]s      Collect everything in a string.
            e#   -1 (none of the above): push 0

~           e# For s string, this evaluates. For 0, it pushes -1.
~           e# For s string, this evaluates. For -1, it pushes 0.
            e# Causes a runtime exception for some sorts of invalid input.
_i:Q        e# Push a copy, cast to Long and save in Q.
\Q=         e# Check if Q is numerically equal to the original.
Qg          e# Compute the sign of Q.
&           e# Logical AND. Pushes 1 for valid input, 0 otherwise.
/           e# Divide by Q the resulting Boolean.
            e# Causes an arithmetic exception for invalid input.

Código (generación de salida)

s,:L     e# Compute the number of digits of Q and save in L.
{        e# Do:
  ;      e#   Discard the integer on the stack.
  Q      e#   Push Q.
  AL(:L# e#   Push 10^(L=-1).
  9L*(   e#   Push 9L-1.
  *)     e#   Multiply and increment.
  9/     e#   Divide by 9.
  -      e#   Subtract from Q.
  _1<    e#   Check if the difference is non-positive.
}g       e# If so, repeat the loop.
(        e# Subtract 1 to account for 1-based indexing.
L)md     e# Push quotient and residue of the division by L+1.
_)p      e# Copy, increment (for 1-based indexing) and print.
\AL#+    e# Add 10^L to the quotient.
_p       e# Print a copy.
s        e# Convert to string.
2$=      e# Retrieve the character that corresponds to the residue.
Dennis
fuente
5

CJam, 75 * 0.75 = 56.25

Esto es bastante rápido, una iteración por dígito del número que contiene la posición deseada. Estoy seguro de que se puede jugar mucho más al golf, es bastante crudo.

q~_i_@<{0/}&:V9{VT>}{T:U;_X*T+:T;A*X):X;}w;U-(_X(:X/\X%10X(#@+s_2$\=S+@)S+@

Dar la posición como entrada, la salida es:

<digit> <position> <full number>

Pruébalo en línea .

Andrea Biondo
fuente
@Dennis Trabajando con todas las entradas ahora :)
Andrea Biondo
Esto todavía no genera un error (como debería) 1.23e1. Sin embargo, comete errores, 1.23456e123456ya que la entrada no puede representarse con un Doble. Además, los últimos casos de prueba tardan 3 minutos.
Dennis
2
@Dennis Now plantea el error. En cuanto al gran caso de prueba ... Maldición. Puede que tenga que reescribir todo el asunto.
Andrea Biondo