Отримайте десятковий!


23

Завдання:

Ваше завдання полягає у наданні трьох входів:

  • чисельник n
  • знаменник d
  • інше ціле число, x

Створіть програму / функцію, яка знаходить xдесяту цифру числа після десяткових знаків.

Технічні характеристики:

  • Діапазон nі dзнаходиться між 1і 2^31 - 1, включно.
  • Діапазон xміж 1і 10,000,000, включно.
    • Ви можете використовувати індексацію на основі 1 або індексацію на основі 0 x. Будь ласка, вкажіть у відповіді, який саме ви використовуєте.
  • nможе бути більше, ніж d.
  • n, dі xвони гарантовано становлять цілі числа (для версії індексу на основі 1 x, якщо ви вирішите використовувати індексацію на основі 0, xтоді це xможе бути 0).
  • Ви можете приймати матеріали будь-яким розумним способом (тобто будь-яким способом, який не є стандартною лазівкою).

Правила:

  • Ви повинні повернути точну xцифру, не коли вона округлена - значить, 15й цифра 1/6, наприклад, не є 7, але 6.
  • Ваша програма повинна працювати на всі xменше 10 мільйонів, якщо ваша мова не підтримує десяткові місця до 10 мільйонів місць.

Приклад вводу / виводу:

У прикладі введення використовується індексація на основі 0, що означає xперехід від 0до 9,999,999. Крім того, "вхід" записується у вигляді рядка з пробілами, що розділяють числа.

1 2 3: 0
5 6 0: 8
5 6 1: 3
1 6 15: 6 (not 7, as it's not rounded)
1 11 2: 0
1 10000 9999999: 0
11 7 1: 7

2
Ця виклик є підгрупою цього
Bassdrop Cumberwubwubwub

8
Я також не вважаю, що це підмножина пі-пі, тому що йдеться про 1 конкретний ірраціональний номер, оскільки цей говорить про кожне раціональне число
Феліпе Нарді Батіста,


1
@FelipeNardiBatista Хммм ... Я можу стверджувати, що це має бути навпаки, оскільки цей виклик детальніше визначається з діапазонами та різними компонентами (це вже було раніше, коли старіший виклик позначається як обробка нового виклику). Я не впевнений, хоча.
клісмік

2
Виконувати вправу можна легко, навіть мовою, яка не має бінтуму ...
RosLuP

Відповіді:


12

Пітон 2 , 25 байт

Порт моєї відповіді Haskell, оскільки Python також підтримує bignums за замовчуванням. Як там, xє 1-індексований.

lambda n,d,x:n*10**x/d%10

Спробуйте в Інтернеті! (запозичивши обгортку Keerthana Prabhakaran.)


Дуже приємно, я провів пару хвилин, гадаючи, "чи це було дійсно так просто"? Порт до Рубі склав би лише 21 байт.
GB

6

Mathematica 33 байт

RealDigits[#/#2,10,1,-#3][[1,1]]&

Індексація на основі 1.

наприклад 10-мільйонна цифра Pi справа від десяткової коми:

%[Pi,1,10^7]
7

займає близько 2 секунд на моїй старій машині.

Ви можете спробувати його в Інтернеті на WolframAlpha (натисніть знак рівності)



5

PHP> = 7,1, 40 байт

<?=bcdiv(($a=$argv)[1],$a[2],$a[3])[-1];

bcdiv

Інтернет-версія


Я отримую цю помилку, коли запускаю ваш код:<br /> <b>Notice</b>: Uninitialized string offset: -1 in <b>[...][...]</b> on line <b>6</b><br />
clismique

@ Qwerp-Derp Вибачте, що вам потрібна версія PHP gte 7.1, і сайт буде це перший візит, не змінюйте його на найвищу версію
Jörg Hülsermann

4

Желе , 7 байт

⁵*×:ƓDṪ

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

Подання функції (але також працює як повна програма). Функції желе можуть приймати лише два аргументи безпосередньо; таким чином, я беру цифру для повернення як лівий аргумент, чисельник як правий аргумент, а знаменник із стандартного вводу (замість використання третього аргументу).

Люди, що звикли до Jelly, можуть усвідомлювати, що повна програма може брати більше двох аргументів, але це робить, що ви втрачаєте доступ до найкоротшого способу запису постійного цілого числа 10, що тут досить актуально. Таким чином, подібний змішаний внесок виглядає скоріше як експлуатування, а не фактичний корисний гольф; Я особисто не погоджуюся з цим, але правило про це дозволяють зараз знаходиться на позначці +40 / -12, тому, поки це передбачено правилами, я можу це також використовувати (і в значній мірі доводиться бути конкурентоспроможними).

Лівий аргумент 1 посилається на цифру відразу після десяткової крапки (".1s цифра"), аргумент від 2 до цифри .01s тощо.

Пояснення

⁵*×:ƓDṪ
⁵*        10 to the power of {the left argument}
  ×       multiplied by {the right argument}
   :      divided by
    Ɠ                standard input
      Ṫ   take the last
     D                  decimal digit

Желе має арифметику довільної точності на цілі числа, тому, попередньо множивши на потужність 10, ми ефективно переміщуємо цифру, яку ми хочемо, до позиції одиниць, де її набагато простіше дістати.


4

sed -r , 93 131 136 байт

s/$/,/
:d
s/,.+/,/
:
s/(1+)(1*;\1;1*,)1{10}?/\21/
t
s/1*/&&&&&&&&&&/
ta
:a
s/1,/,/
td
s/.+,//

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

( Див. Вихід у десятковій кількості )

Здійснює введення одинарними та виводить унарними, а програма 1-індексованою. На щастя, цей виклик вже підготував мене до цього.

Концепція схожа, обидва реалізують тривалий поділ. Тут я виконую тривалий поділx , деx цифра після десяткового знака, яку я маю знайти. Після кожної ітерації я відкидаю попередні знаки після коми, оскільки вони більше не потрібні.

Проводячи поділ, програма працює у форматі dividend;divisor;x,result .

s/$/,/ додає цю кому, кома потрібна для відокремлення результату від усього іншого

Далі слід основний цикл програми

:d етикетка d

  • s/,.+/,/ видаліть все після коми

  • : порожня етикетка

    • s/(1+)(1*;\1;1*,)1{10}?/\21/ виконайте поділ, додаючи 1 результат до кожної ітерації, одночасно видаляючи блоки з 10 безперервних 1s в результаті
  • t гілка на порожню мітку, інакше кажучи, цикл, поки дивіденд не буде вичерпаний

  • s/1*/&&&&&&&&&&/ помножте дивіденд на 10, щоб підготуватися до наступної ітерації

  • ta гілка для позначення a

  • :aпозначка a, цей рядок і рядок, наведений вище, необхідні для tdроботи

  • s/1,/,/ відняти 1 від х

tdумовна гілка на d, це спрацьовує, якщо відбулася успішна заміна з моменту останньої умовної гілки, оскільки s/1*/&&&&&&&&&&/вона завжди є успішною, tdзавжди буде спрацьовувати, але, вводячи гілку а, ми фіксуємо це так, що це залежить тільки від попередньої заміни

s/.+,// нарешті, видаліть усе, крім результату



3

REXX, 76 байт

(Не дуже короткий, але думав, що це зробить зміни, щоб зробити це в REXX) ​​Rexx заснований на 1 визначенні.

arg n d x
numeric digits x+10
y=n/d
parse var y "." +(x) z
say left(z,1,"0")

Пояснення:

  1. Прочитайте введення чисел
  2. Гарантія достатньо значущих цифр (за замовчуванням - 9)
  3. Обчисліть
  4. Розкол. Знайдіть десяткову точку, порахуйте вперед символи "x", візьміть наступні символи і поставте в "z"
  5. Роздрукуйте першу цифру. Накладка з 0, щоб бути впевненим.

Об'єднання 3 і 4 насправді збільшує їх через зміну синтаксису:

parse value n/d with "." +x z +1

Для не-REXXers: рядки та числа повністю взаємозамінні в REXX. Вони визначаються тим, як ти дієш на них. Таким чином, ви можете проаналізувати число, використовуючи функції жала без перетворення. Наприклад

"27" + "28"

повертає 55, а не 2728!


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

tutorialspoint.com/execute_rexx_online.php Єдиною проблемою є те, що я не зміг розібратися, як вводити значення в інтерпретатор. Отже, для тестових цілей я використовував завдання для встановлення значень на початку.
theblitz

1
Схоже, що інтерпретатор працює, якщо ви даєте вхід CLI rexx main.rexx 1 2 3. Ви повинні зазначити у своїй відповіді, що вхід 1-індексований.
Мего

Не помітив можливість введення, тому що я просто натиснув кнопку "виконати" вгорі. Дух.
theblitz

2

Пакетна, 70 байт

@set n=%1
@for /l %%x in (0,1,%3)do @set/an=n%%%2*10
@cmd/cset/an/%2

@FelipeNardiBatista працював для мене, коли я спробував це.
Ніл

2

Збірка мови процесор Intel x86, 50 байт

00000940  53                push ebx
00000941  8B5C240C          mov ebx,[esp+0xc]
00000945  8B4C2410          mov ecx,[esp+0x10]
00000949  31C0              xor eax,eax
0000094B  48                dec eax
0000094C  81C102000000      add ecx,0x2
00000952  721A              jc 0x96e
00000954  81FB00000000      cmp ebx,0x0
0000095A  7412              jz 0x96e
0000095C  8B442408          mov eax,[esp+0x8]
00000960  31D2              xor edx,edx
00000962  F7F3              div ebx
00000964  49                dec ecx
00000965  7407              jz 0x96e
00000967  8D0492            lea eax,[edx+edx*4]
0000096A  01C0              add eax,eax
0000096C  EBF2              jmp short 0x960
0000096E  5B                pop ebx
0000096F  C20C00            ret 0xc

трасляція в насм

; u32 __stdcall rdiv(u32 a, u32  b, u32 c)
; 8a, 12b, 16c
      align   4
rdiv:                   ; c<0xFFFFFFFE and b!=0
      push    ebx       ; something as for(;a=10*(a%b),c--;);return a/b
      mov     ebx,  dword[esp+  12]
      mov     ecx,  dword[esp+  16]
      xor     eax,  eax
      dec     eax
      add     ecx,  2
      jc      .z
      cmp     ebx,  0
      je      .z            
      mov     eax,  dword[esp+  8]
.1:   xor     edx,  edx
      div     ebx
      dec     ecx
      jz      .z
      lea     eax,  [edx+edx*4]
      add     eax,  eax
      jmp     short  .1     ; a=5*a;a+=a=>a=10*a
.z:       
      pop     ebx
      ret     12

Для параметра 'c' діапазон починається від 0; було б 0..0xfffffffd. Якщо параметри b = 0 або c виходять за межі 0..0xfffffffd, він поверне -1



1

C, 49 43 байти

f(a,b,i){for(;a=10*(a%b),i--;);return a/b;}

Аргумент 'i' - це 0-індексація. Код тесту та результат

main()
{int i;
 for(i=0;i<20;++i)
     printf("%u", f(12,11,i));

 printf("\nf(1,2,3)=%d\n",f(1,2,3));
 printf("f(5,6,0)=%d\n",f(5,6,0));
 printf("f(5,6,1)=%d\n",f(5,6,1));
 printf("f(1,6,15)=%d\n",f(1,6,15));
 printf("f(1,11,2)=%d\n",f(1,11,2));
 printf("f(1,10000,9999999)=%d\n",f(1,10000,9999999));
 printf("f(11,7,1)=%d\n",f(11,7,1));
}

f(1,2,3)=0
f(5,6,0)=8
f(5,6,1)=3
f(1,6,15)=6
f(1,11,2)=0
f(1,10000,9999999)=0
f(11,7,1)=7 

1

Ява 7, 146 139 137 133 128 122 байт

-3 байти, завдяки Еріку Атгольферу, я зовсім забув, що імпорт не повинен був бути в їх власній лінії

-4 байти завдяки Qwerp-Derp за переміщення n% d до конструктора

-6 байт дякую Кевіну Крейсейну за видалення toString ()

Я сподіваюсь, що так відбувається підрахунок байтів для функцій java з імпортом

import java.math.*;char a(int n,int d,int x){return (new BigDecimal(n%d).divide(new BigDecimal(d),x+1,1)+"").charAt(x+2);}

Використовує клас BigDecimal Java для отримання точного подання десяткового розширення. Зверніть увагу, що це не найшвидший код, який колись працює, але в кінцевому підсумку він дає правильний вихід для всіх тестових випадків. Невикористаний код:

import java.math.*;
char a(int n, int d, int x){
    BigDecimal num = new BigDecimal(n%d); // reduce improper fractions
    BigDecimal div = new BigDecimal(d);
    BigDecimal dec = num.divide(div, x+1, 1); // precision of x + 1, round down
    return (dec+"").charAt(x+2); //xth char after decimal
}

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


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

Я рахую 137 байт
Kritixi Lithos

Потрібно
помилково

Хіба ви не можете просто замінити BigDecimal(n)з BigDecimal(n%d), і позбутися від n=n%d?
клісмік

Ви можете видалити .toString()та використовувати +""натомість (з двома додатковими дужками).
Кевін Круїссен

1

Clojure, 39 байт

#(mod(int(/(*(Math/pow 10 %3)%)%2))10))

анонімна функція з аргументами, n,d,xде xвикористовується одна заснована індексація.


1

F # (.NET Core) , 30 байт

let f n d x=n*pown 10I x/d%10I

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

(використовуйте індексацію на основі 1)


Я рахую 33 байти. Я б також запропонував додати спробувати онлайн! посилання.
wastl

Я мав неправильну функцію у своєму буфері обміну. Спасибі.
Ще один метапрограміст

1

Groovy, 30 байт

{n,d,x->(n*10**x/d as int)%10}

x використовує 1 індексацію на основі.

Пояснення:

{n,d,x->    // closure with three arguments, n, d, x
 n*10**x    // multiply n with 10 to the power of x
 /d         // divide by d
 as int     // convert from BigDecimal to int
 )%10       // modulo 10 to get the answer
}



0

JavaScript (ES6), 34 байти

(n,d,x)=>`${n/d}`.split`.`[1][x]|0

x заснований на 0

f=
(n,d,x)=>`${n/d}`.split`.`[1][x]|0

console.log(f(1,2,3))
console.log(f(5,6,0))
console.log(f(5,6,1))
console.log(f(1,6,15))
console.log(f(1,11,2))
console.log(f(1,10000,10000000))
console.log(f(11,7,1))
console.log(f(2000,7,0))


На жаль, як і моє рішення, це не вдасться з довгими децималами; спробуйте f(1,7,10000000), наприклад.
Кудлатий

0

Python 2 , 32 байти

Використовує 0-індексацію

lambda n,d,x:int(10**-~x*n/d)%10

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

Редагувати:

Повернувся до оригінального рішення, як видно з відповіді Ørjan Johansen, що це працює, але я більше не буду його гольфувати


2
Якщо він недійсний, його слід видалити.
Ерік Аутгольфер

як більшість відповідей поки що
Феліпе Нарді Батіста

@EriktheOutgolfer виправив це ...
Феліпе Нарді Батіста

Чи використовуєте ви 1-індексацію?
Ерік Аутгольфер


0

Groovy, 55 байт

{n,d,x->z='0'*x;Eval.me("$n.$z/$d.$z").toString()[x-1]}

Пояснено з використанням 1,11,2:

{
    n,d,x->          // I've already lost to Jelly by the end of this line.
    z='0'*x;         // Set z equal to 2 0's.
    Eval.me          // Evaluate as groovy code...
    ("$n.$z/$d.$z")  // 1.00g/11.00g (Automatically set precision using # 0s).
   .toString()[x-1]  // Get 2nd digit of division.
}

0

Аксіома, 71 61 76 байт

f(a:NNI,b:PI,n:NNI):NNI==(repeat(a:=10*(a rem b);n=0=>break;n:=n-1);a quo b)

n - 0-індексація [0..M]. Код тесту та результат

(19) ->    f(1,2,3)=0
   (19)  0= 0
(20) ->     f(5,6,0)=8
   (20)  8= 8
(21) ->     f(5,6,1)=3
   (21)  3= 3
(22) ->     f(1,6,15)=6
   (22)  6= 6
(23) ->     f(1,11,2)=0
   (23)  0= 0
(24) ->     f(1,10000,9999999)=0
   (24)  0= 0
(25) ->     f(11,7,1)=7
   (25)  7= 7

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.