Deretan bilangan alami

22

Definisi

Ada deretan tak terhingga dari bilangan natural gabungan (bilangan bulat positif, dimulai dengan 1):

1234567891011121314151617181920212223...

Tantangan

  • Tulis program dalam bahasa apa pun, yang menerima nomor posisi sebagai input, dan mengeluarkan angka dari posisi itu di baris yang ditentukan di atas.
  • Nomor posisi adalah bilangan bulat positif ukuran acak. Itu posisi pertama adalah 1, menghasilkan digit keluaran '1'
  • Input berupa desimal (mis. 13498573249827349823740000191), atau e-notasi (mis. 1.2e789) sesuai dengan bilangan bulat positif.
  • Program harus berakhir dalam waktu yang wajar (10 detik pada PC / Mac modern), diberi indeks yang sangat besar sebagai input (mis. 1e123456 - yaitu 1 dengan 123456 nol). Jadi, loop iterasi sederhana tidak dapat diterima.
  • Program harus diakhiri dengan kesalahan dalam 1 detik, jika diberi input yang tidak valid. Misalnya. 1.23e (tidak valid), atau 1.23e1 (sama dengan 12.3 - bukan bilangan bulat)
  • Tidak apa-apa menggunakan perpustakaan BigNum publik untuk mem-parsing / menyimpan nomor dan melakukan operasi matematika sederhana pada mereka (+ - * / exp). Tidak ada penalti byte yang diterapkan.
  • Kode terpendek menang.

TL; DR

  • Input: bignum integer
  • Output: digit pada posisi itu dalam baris tak terbatas 123456789101112131415...

Beberapa kasus uji penerimaan

dalam notasi "Input: Output". Mereka semua harus lulus.

  • 1: 1
  • 999: 9
  • 10000000: 7
  • 1e7: 7 (sama seperti baris di atas)
  • 13498573249827349823740000191: 6
  • 1.1e10001: 5
  • 1e23456: 5
  • 1.23456e123456: 4
  • 1e1000000: 0
  • 1.23e: kesalahan (sintaks tidak valid)
  • 0: kesalahan (di luar batas)
  • 1.23e1: kesalahan (bukan bilangan bulat)

Bonus!

Keluarkan angka posisi digit di dalam nomor tersebut, dan nomor keluaran itu sendiri. Sebagai contoh:

  • 13498573249827349823740000191: 6 24 504062383738461516105596714
    • Itu digit '6' di posisi 24 dari nomor '50406238373846151610559 6 714'
  • 1e1000000: 0 61111 1000006111141666819445...933335777790000
    • Digit '0' di posisi 61111 dari angka panjang 999995-digit saya tidak akan sertakan di sini.

Jika Anda memenuhi tugas bonus, kalikan ukuran kode Anda dengan 0,75

Kredit

Tugas ini diberikan di salah satu pertemuan devclub.eu pada tahun 2012, tanpa persyaratan jumlah besar. Oleh karena itu, sebagian besar jawaban yang diajukan adalah loop sepele.

Selamat bersenang-senang!

metalim
sumber
Saya benar-benar tidak mengerti tantangannya. Apakah kita seharusnya mengambil input dan menampilkan nomor pada posisi itu?
The_Basset_Hound
1
Ini adalah urutan OEIS 33307 .
Tyilo
2
@ Vihan Menggunakan beberapa perpustakaan bignum publik dapat diterima. Tidak ada penalti. Tentu saja termasuk solusi ke perpustakaan dan menggunakan perpustakaan dalam satu-liner mempertimbangkan kecurangan. Akal sehat berlaku di sini.
metalim
1
Hanya ingin memamerkan solusi F # yang mengejutkan , mencatat 44 byte. Memang, itu hanya dapat menangani indeks hingga 2 ^ 31-1 (dan masih mencoba menghitung nilai itu saat saya menulis ini). Saya tidak memposting ini karena memang melanggar aturan, tapi saya akan mengatakan itu cukup bagus untuk F #!
Jwosty
7
Persyaratan untuk menangani input seperti secara 1.23456e123456sewenang - wenang menghukum bahasa yang tidak dapat memproses nilai-nilai tersebut secara asli dan mengharuskan mereka untuk melakukan pemrosesan string yang bersinggungan dengan tantangan.
xnor

Jawaban:

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=

Program ini panjangnya 104 byte dan memenuhi syarat untuk bonus.

Baris baru ini murni kosmetik. Baris pertama mem-parsing input, yang kedua menghasilkan output.

Cobalah online!

Ide

Untuk bilangan bulat positif k , ada 9 × 10 k-1 bilangan bulat positif dengan tepat digit k (tidak termasuk angka nol di depan). Jadi, jika kita menggabungkan semuanya, kita mendapatkan bilangan bulat 9 × n × 10 k-1 .

Sekarang, menggabungkan semua bilangan bulat n atau kurang menghasilkan bilangan bulat

rumus

digit.

Untuk input q yang diberikan , kami mencoba menentukan n tertinggi sehingga ekspresi di atas lebih kecil dari q . Kita atur n: = ⌈ log 10 q⌉-1 , lalu n: = ⌈ log 10 q⌉-2 , dll. Hingga ekspresi yang diinginkan menjadi lebih kecil dari q , kurangi ekspresi yang dihasilkan dari q (menghasilkan r ) dan simpan yang terakhir nilai n dalam l .

r sekarang menetapkan indeks dalam gabungan semua bilangan bulat positif l + 1 digit, yang berarti bahwa output yang diinginkan adalah r% (l + 1) digit ke - r dari (/ + 1) bilangan bulat ke - l + 1 digit.

Kode (parsing 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.

Kode (pembuatan keluaran)

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
sumber
5

CJam, 75 * 0.75 = 56.25

Ini cukup cepat, satu iterasi per digit dari angka yang berisi posisi yang diinginkan. Saya yakin ini bisa lebih banyak bermain golf, cukup kasar.

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

Beri posisi sebagai input, outputnya adalah:

<digit> <position> <full number>

Cobalah online .

Andrea Biondo
sumber
@ Dennis Bekerja dengan semua input sekarang :)
Andrea Biondo
Ini masih tidak menimbulkan kesalahan (sebagaimana mestinya) untuk 1.23e1. Itu kesalahan, bagaimanapun, untuk 1.23456e123456, karena input tidak dapat diwakili oleh Double. Juga, test case terakhir membutuhkan 3 menit.
Dennis
2
@ Dennis Sekarang memunculkan kesalahan. Adapun kasus ujian besar ... Sial. Saya mungkin harus menulis ulang semuanya.
Andrea Biondo