Rangée de nombres naturels

22

Définition

Il y a une rangée infinie de nombres naturels concaténés (entiers positifs, commençant par 1):

1234567891011121314151617181920212223...

Défi

  • Programme d'écriture dans n'importe quelle langue, qui accepte le numéro de position comme entrée et génère un chiffre à partir de cette position dans la ligne définie ci-dessus.
  • Le numéro de position est un entier positif de taille arbitraire. C'est la première position est 1, ce qui donne le chiffre de sortie «1»
  • L'entrée est soit décimale (par exemple 13498573249827349823740000191), soit en notation électronique (par exemple 1.2e789) correspondant à un entier positif.
  • Le programme doit se terminer dans un délai raisonnable (10 secondes sur PC / Mac moderne), étant donné un très grand index en entrée (par exemple 1e123456 - c'est-à-dire 1 avec 123456 zéros). Ainsi, une simple boucle d'itération n'est pas acceptable.
  • Le programme doit se terminer avec une erreur en 1 s, s'il reçoit une entrée non valide. Par exemple. 1.23e (invalide) ou 1.23e1 (égal à 12,3 - pas un entier)
  • Il est correct d'utiliser la bibliothèque publique BigNum pour analyser / stocker des nombres et effectuer des opérations mathématiques simples sur eux (+ - * / exp). Aucune pénalité d'octet appliquée.
  • Le code le plus court gagne.

TL; DR

  • Entrée: entier bignum
  • Sortie: chiffre à cette position sur une ligne infinie 123456789101112131415...

Quelques cas de test d'acceptation

en notation "Input: Output". Tous devraient passer.

  • 1: 1
  • 999: 9
  • 10000000: 7
  • 1e7: 7 (identique à la ligne ci-dessus)
  • 13498573249827349823740000191: 6
  • 1.1e10001: 5
  • 1e23456: 5
  • 1.23456e123456: 4
  • 1e1000000: 0
  • 1.23e: erreur (syntaxe non valide)
  • 0: erreur (hors limites)
  • 1.23e1: erreur (pas un entier)

Prime!

Numéro de position du chiffre de sortie à l'intérieur du numéro et numéro de sortie lui-même. Par exemple:

  • 13498573249827349823740000191: 6 24 504062383738461516105596714
    • Ce chiffre de « 6 » à la position 24 du nombre « 50406238373846151610559 6 714 »
  • 1e1000000: 0 61111 1000006111141666819445...933335777790000
    • Chiffre «0» à la position 61111 du numéro long à 999995 chiffres que je ne vais pas inclure ici.

Si vous remplissez la tâche bonus, multipliez la taille de votre code par 0,75

Crédit

Cette tâche a été donnée lors d'un des rassemblements devclub.eu en 2012, sans grande exigence de nombre. Par conséquent, la plupart des réponses soumises étaient des boucles triviales.

S'amuser!

metalim
la source
Je ne comprends vraiment pas quel est le défi. Sommes-nous censés prendre l'entrée et la sortie du nombre à cette position?
The_Basset_Hound
1
Il s'agit de la séquence OEIS 33307 .
Tyilo
2
@vihan L'utilisation d'une bibliothèque publique bignum est acceptable. Pas de pénalité. Bien sûr, l'inclusion de la solution dans la bibliothèque et l'utilisation de la bibliothèque dans une seule ligne envisagent de tricher. Le bon sens s'applique ici.
metalim
1
Je voulais juste montrer une solution F # étonnamment concise , cadencée à 44 octets. Certes, il ne peut gérer que les indices jusqu'à 2 ^ 31-1 (et il essaie toujours de calculer cette valeur au moment où j'écris ceci). Je ne poste pas cela cependant car il enfreint les règles, mais je dirais que c'est plutôt bon pour F #!
Jwosty
7
Les exigences pour gérer les entrées comme 1.23456e123456punissent arbitrairement les langues qui ne peuvent pas traiter ces valeurs de manière native et les obligent à effectuer un traitement de chaîne tangentiel au défi.
xnor

Réponses:

12

CJam , 78 octets

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=

Le programme est de 104 octets de long et se qualifie pour le bonus.

La nouvelle ligne est purement cosmétique. La première ligne analyse l'entrée, la seconde génère la sortie.

Essayez-le en ligne!

Idée

Pour tout entier positif k , il existe 9 × 10 k-1 entiers positifs d'exactement k chiffres (sans compter les zéros de tête). Ainsi, si nous les concaténons tous, nous obtenons un entier de 9 × n × 10 k-1 .

Maintenant, concaténer tous les entiers de n chiffres ou moins donne un entier de

formule

chiffres.

Pour une entrée q donnée , nous essayons de déterminer le n le plus élevé de sorte que l'expression ci-dessus soit plus petite que q . Nous fixons n: = ⌈log 10 q⌉-1 , puis n: = ⌈log 10 q⌉-2 , etc. jusqu'à ce que l'expression souhaitée devienne inférieure à q , soustrayons l'expression résultante de q (donnant r ) et sauvegardons la dernière valeur de n dans l .

r spécifie maintenant l'indice dans la concaténation de tous les entiers positifs de l + 1 chiffres, ce qui signifie que la sortie souhaitée est le r% (l + 1) ème chiffre du r / (l + 1) ème entier de l + 1 chiffres.

Code (analyse d'entrée)

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.

Code (génération de sortie)

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
la source
5

CJam, 75 * 0,75 = 56,25

C'est assez rapide, une itération par chiffre du nombre qui contient la position souhaitée. Je suis sûr qu'il peut être joué beaucoup plus au golf, c'est assez brut comme ça.

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

Donnez la position en entrée, la sortie est:

<digit> <position> <full number>

Essayez-le en ligne .

Andrea Biondo
la source
@Dennis Travailler avec toutes les entrées maintenant :)
Andrea Biondo
Cela ne génère toujours pas d'erreur (comme il se doit) pour 1.23e1. Il comporte cependant des erreurs, 1.23456e123456car l'entrée ne peut pas être représentée par un double. De plus, le dernier cas de test prend 3 minutes.
Dennis
2
@Dennis soulève maintenant l'erreur. Quant au grand cas de test ... Merde. Je vais peut-être devoir tout réécrire.
Andrea Biondo