Ряд натуральних чисел


22

Визначення

Існує нескінченний ряд з'єднаних натуральних чисел (додатні цілі числа, починаючи з 1):

1234567891011121314151617181920212223...

Виклик

  • Напишіть програму будь-якою мовою, яка приймає номер позиції як вхідний і виводить цифру з цієї позиції у рядку, визначеному вище.
  • Номер позиції - ціле число довільного розміру. Це перша позиція 1, даючи вихідну цифру '1'
  • Введення або в десятковій частині (наприклад, 13498573249827349823740000191), або в електронному позначенні (наприклад, 1.2e789), що відповідає додатному цілому числу.
  • Програма повинна закінчитися в розумний час (10 секунд на сучасних ПК / Mac), враховуючи дуже великий індекс як вхід (наприклад, 1e123456 - тобто 1 з 123456 нулями). Отже, простий цикл ітерації неприйнятний.
  • Програма повинна закінчитися з помилкою за 1 с, якщо дано недійсний ввід. Напр. 1,23е (недійсне) або 1,23е1 (дорівнює 12,3 - не ціле число)
  • Добре використовувати публічну бібліотеку BigNum для розбору / зберігання чисел та виконання простих математичних операцій над ними (+ - * / exp). Байтовий штраф не застосовується.
  • Найкоротший код виграє.

TL; DR

  • Вхід: bignum ціле число
  • Вихід: цифра на цій позиції у нескінченному рядку 123456789101112131415...

Деякі тестові випадки приймання

у позначенні "Введення: вихід". Усі вони повинні пройти.

  • 1: 1
  • 999: 9
  • 10000000: 7
  • 1e7: 7 (те саме, що і рядок вище)
  • 13498573249827349823740000191: 6
  • 1.1e10001: 5
  • 1e23456: 5
  • 1.23456e123456: 4
  • 1e1000000: 0
  • 1.23e: помилка (недійсний синтаксис)
  • 0: помилка (поза межами)
  • 1.23e1: помилка (не ціле число)

Бонус!

Вихідний номер позиційного номера всередині номера та номер виводу. Наприклад:

  • 13498573249827349823740000191: 6 24 504062383738461516105596714
    • Це цифра '6' у позиції 24 номера '50406238373846151610559 6 714'
  • 1e1000000: 0 61111 1000006111141666819445...933335777790000
    • Цифру "0" на позиції 61111 з 999995-значного довгого числа я сюди не включатиму.

Якщо ви виконуєте бонусне завдання, помножте розмір коду на 0,75

Кредит

Це завдання було дано на одному з зборів devclub.eu у 2012 році, без великої кількості. Отже, більшість поданих відповідей були тривіальними петлями.

Веселіться!


Я справді не розумію, у чому полягає виклик. Чи слід брати вхід і виводити номер у цій позиції?
The_Basset_Hound


2
@vihan Використання публічної бібліотеки bignum є прийнятною. Без штрафу. Звичайно, включення рішення в бібліотеку та використання бібліотеки в одній лайнері розглядає обман. Тут застосовується здоровий глузд.
металлім

1
Просто хотілося показати напрочуд лаконічне рішення F # , яке працює в 44 байти. Зрозуміло, він може обробляти лише показники до 2 ^ 31-1 (і все ще намагається обчислити це значення, коли я це пишу). Я не публікую це, хоча тому, що він дійсно порушує правила, але я б сказав, що це досить добре для F #!
Jwosty

7
Вимоги до обробки вхідних даних, таких як 1.23456e123456довільно, карають мови, які не можуть обробити такі значення спочатку, і вимагає, щоб вони виконували обробку рядків, яка дотична до завдання.
xnor

Відповіді:


12

CJam , 78 байт

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=

Програма завдовжки 104 байти і кваліфікується на бонус.

Новий рядок суто косметичний. Перший рядок аналізує вхід, другий генерує вихід.

Спробуйте в Інтернеті!

Ідея

Для будь-якого натурального цілого k існує 9 × 10 k-1 додатних цілих чисел, що мають рівно k цифр (не рахуючи провідні нулі). Таким чином, якщо ми об'єднаємо їх усі, ми отримаємо ціле число 9 × n × 10 k-1 .

Тепер, об'єднання всіх цілих чисел з n або менших цифр дає ціле число

формула

цифр.

Для заданого входу q ми намагаємося визначити найвищий n такий, що вищевказаний вираз є меншим за q . Встановлюємо n: = ⌈log 10 q⌉-1 , потім n: = ⌈log 10 q⌉-2 і т. Д. До тих пір, поки потрібний вираз не стане меншим за q , віднімаємо отриманий вираз з q (вихід r ) і зберігаємо останнє значення n в л .

r тепер вказує індекс в конкатенації всіх натуральних чисел l + 1 цифр, що означає, що бажаний вихід - r% (l + 1) цифри r / (l + 1) -го цілого числа l + 1 цифр.

Код (синтаксичний аналіз)

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.

Код (генерація випуску)

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

Це досить швидко, одна ітерація на цифру числа, що містить бажану позицію. Я впевнений, що можна пограти в гольф набагато більше, він досить сирий, як є.

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

Подайте позицію як вхід, вихід:

<digit> <position> <full number>

Спробуйте в Інтернеті .


@Dennis Зараз працюю з усіма вкладами :)
Andrea Biondo

Це все ще не викликає помилки (як слід) для 1.23e1. Однак це помилка, 1.23456e123456оскільки вхід не може бути представлений подвійним. Також останні тестові випадки займають 3 хвилини.
Денніс

2
@Dennis Тепер викликає помилку. Що стосується великого тестового випадку ... Чорт. Можливо, мені доведеться переписати всю справу.
Андреа Біондо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.