Fila di numeri naturali


22

Definizione

Esiste una fila infinita di numeri naturali concatenati (numeri interi positivi, che iniziano con 1):

1234567891011121314151617181920212223...

Sfida

  • Scrivi il programma in qualsiasi lingua, che accetta il numero di posizione come input e produca cifre da quella posizione nella riga sopra definita.
  • Il numero di posizione è un numero intero positivo di dimensione arbitraria. Questa è la prima posizione è 1, che fornisce la cifra in uscita '1'
  • L'immissione è in decimale (es. 13498573249827349823740000191) o notazione elettronica (es. 1.2e789) corrispondente all'intero positivo.
  • Il programma deve terminare in un tempo ragionevole (10 secondi su un moderno PC / Mac), dato un indice molto grande come input (es. 1e123456 - ovvero 1 con 123456 zero). Così, semplice ciclo di iterazione non è accettabile.
  • Il programma deve terminare con un errore in 1 s, se viene fornito un input non valido. Per esempio. 1.23e (non valido) o 1.23e1 (uguale a 12.3 - non un numero intero)
  • Va bene usare la libreria pubblica BigNum per analizzare / memorizzare numeri e fare semplici operazioni matematiche su di essi (+ - * / exp). Nessuna penalità di byte applicata.
  • Il codice più corto vince.

TL; DR

  • Input: numero intero bignum
  • Output: cifra in quella posizione in fila infinita 123456789101112131415...

Alcuni casi di test di accettazione

nella notazione "Input: Output". Tutti dovrebbero passare.

  • 1: 1
  • 999: 9
  • 10000000: 7
  • 1e7: 7 (uguale alla riga sopra)
  • 13498573249827349823740000191: 6
  • 1.1e10001: 5
  • 1e23456: 5
  • 1.23456e123456: 4
  • 1e1000000: 0
  • 1.23e: errore (sintassi non valida)
  • 0: errore (fuori limite)
  • 1.23e1: errore (non un numero intero)

Bonus!

Numero di posizione della cifra di output all'interno del numero e numero di output stesso. Per esempio:

  • 13498573249827349823740000191: 6 24 504062383738461516105596714
    • È la cifra '6' nella posizione 24 del numero '50406238373846151610559 6 714'
  • 1e1000000: 0 61111 1000006111141666819445...933335777790000
    • Cifra '0' nella posizione 61111 di un numero lungo di 999995 cifre che non includerò qui.

Se esegui l'attività bonus, moltiplica la dimensione del tuo codice per 0,75

Credito

Questo compito è stato assegnato in una delle riunioni di devclub.eu nel 2012, senza un numero elevato di requisiti. Quindi, la maggior parte delle risposte presentate erano loop banali.

Divertiti!


Davvero non capisco quale sia la sfida. Dobbiamo prendere l'input e l'output del numero in quella posizione?
The_Basset_Hound

1
Questa è la sequenza OEIS 33307 .
Tyilo,

2
@vihan L'utilizzo di una libreria pubblica bignum è accettabile. Nessuna penalità Ovviamente includere la soluzione nella libreria e usare la libreria in un solo passaggio sta prendendo in considerazione l'idea di barare. Il buon senso si applica qui.
metalim,

1
Volevo solo mostrare una soluzione F # sorprendentemente concisa , con un clock di 44 byte. Certo, può gestire solo indici fino a 2 ^ 31-1 (e sta ancora cercando di calcolare quel valore mentre scrivo questo). Non sto pubblicando questo però perché in effetti infrange le regole, ma direi che è abbastanza buono per F #!
Jwosty,

7
I requisiti per gestire input come 1.23456e123456puniscono arbitrariamente i linguaggi che non possono elaborare tali valori in modo nativo e richiedono loro di eseguire l'elaborazione delle stringhe che è tangenziale alla sfida.
xnor

Risposte:


12

CJam , 78 byte

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=

Il programma è lungo 104 byte e si qualifica per il bonus.

La nuova linea è puramente cosmetica. La prima riga analizza l'input, la seconda genera l'output.

Provalo online!

Idea

Per qualsiasi numero intero positivo k , esistono numeri interi positivi 9 × 10 k-1 di esattamente k cifre (senza contare gli zeri iniziali). Pertanto, se li concateniamo tutti, otteniamo un numero intero di 9 × n × 10 k-1 .

Ora, concatenando tutti i numeri interi di n o meno cifre si ottiene un numero intero di

formula

cifre.

Per un dato input q , proviamo a determinare il n più alto in modo che l'espressione sopra sia più piccola di q . Abbiamo impostato n: = ⌈log 10 q⌉-1 , quindi n: = ⌈log 10 q⌉-2 , ecc finché l'espressione desiderata diviene inferiore q , sottrarre l'espressione risultante da q (cedevole r ) e salvare l'ultimo valore di n in l .

r ora specifica l'indice nella concatenazione di tutti gli interi positivi di l + 1 cifre, il che significa che l'output desiderato è la r% (l + 1) th cifra del r / (l + 1) th integer di l + 1 cifre.

Codice (analisi di input)

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.

Codice (generazione output)

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.

5

CJam, 75 * 0,75 = 56,25

Questo è abbastanza veloce, una iterazione per cifra del numero che contiene la posizione desiderata. Sono sicuro che può essere giocato a golf molto di più, è piuttosto grezzo così com'è.

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

Dare la posizione come input, l'output è:

<digit> <position> <full number>

Provalo online .


@Dennis Lavorando con tutti gli input ora :)
Andrea Biondo,

Questo non genera ancora un errore (come dovrebbe) per 1.23e1. Errori, tuttavia, per 1.23456e123456, poiché l'input non può essere rappresentato da un doppio. Inoltre, gli ultimi casi di test richiedono 3 minuti.
Dennis,

2
@Dennis Now genera l'errore. Per quanto riguarda il grande caso di prova ... Accidenti. Potrei dover riscrivere il tutto.
Andrea Biondo,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.