Получить десятичную!


23

Задача:

Ваша задача, когда дано три входа:

  • числитель n
  • знаменатель d
  • другое целое число, x

Создайте программу / функцию, которая находит xth-ю цифру числа после десятичного знака.

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

  • Диапазон 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цифру th, а не округленную - таким образом , например, не 15цифра th , но .1/676
  • Ваша программа должна работать для всех 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
@FelipeNardiBatista Хммм ... Я мог бы поспорить, что это должно быть наоборот, так как этот вызов более определен с диапазонами и прочим (это уже было раньше, когда более старый вызов помечался как дублирование нового вызова). Я не уверен, хотя.
clismique

2
Упражнение можно легко выполнить даже на языке, который не имеет значения ...
RosLuP

Ответы:


12

Python 2 , 25 байт

Порт моего ответа на Haskell, так как Python также поддерживает bignums по умолчанию. Как там, x1-х индексируется.

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

Попробуйте онлайн! (одолжив обертку Кеертхана Прабхакарана.)


Очень приятно, я потратил пару минут на размышления "неужели это так просто?" Порт для Ruby будет всего 21 байт.
GB

6

Mathematica 33 байта

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

Индексирование на основе 1.

например, 10-миллионная цифра числа Пи справа от десятичной точки:

%[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, и сайт будет первым посещением, не меняйте его на самую высокую версию
Йорг Хюльсерманн

4

Желе , 7 байт

⁵*×:ƓDṪ

Попробуйте онлайн!

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

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

Левый аргумент 1 относится к цифре сразу после десятичной точки («цифра .1s»), аргумент от 2 к цифре .01с и т. Д.

объяснение

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

У Jelly есть арифметика произвольной точности на целых числах, поэтому, предварительно умножив на 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 непрерывных 1 с в результате
  • t переход на пустую метку, другими словами, цикл, пока дивиденд не будет исчерпан

  • s/1*/&&&&&&&&&&/ умножьте дивиденд на 10, чтобы подготовиться к следующей итерации

  • ta ветвь для обозначения

  • :aобозначить a, эта строка и строка выше необходимы для tdработы

  • s/1,/,/ вычесть 1 из х

tdусловная ветвь к d, это срабатывает, если с момента последней условной ветки произошла успешная подстановка, поскольку s/1*/&&&&&&&&&&/она всегда успешна, tdвсегда будет срабатывать, но введя ветвь a, мы исправим это так, что она зависит только от предыдущей подстановки

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. Распечатайте первую цифру. Pad с 0, чтобы быть уверенным.

Объединение 3 и 4 фактически делает его длиннее из-за изменения синтаксиса:

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

Для не REXX: строки и числа полностью взаимозаменяемы в REXX. Они определяются тем, как вы действуете на них. Таким образом, вы можете анализировать число, используя функции sting без преобразования. Например

"27" + "28"

возвращает 55, а не 2728!


Не могли бы вы добавить ссылку на переводчика? Я предполагаю, что много пользователей незнакомы с этим языком.
Mego

tutorialspoint.com/execute_rexx_online.php Единственная проблема в том, что я не могу понять, как вводить значения в интерпретаторе. Итак, для целей тестирования я использовал назначения для установки значений в начале.
Theblitz

1
Похоже, что интерпретатор работает, если вы даете ввод CLI, как rexx main.rexx 1 2 3. Вы должны упомянуть в своем ответе, что вход 1 индексирован.
Mego

Не заметил возможности ввода, потому что я просто нажал кнопку «Выполнить» вверху. Duh.
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 на языке CPU, 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 байта благодаря Эрику Outgolfer, я полностью забыл, что импорт не должен был быть на их собственной линии

-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);}

Использует класс Java BigDecimal, чтобы получить точное представление десятичного расширения. Обратите внимание, что это не самый быстрый исполняемый код, но он в конечном итоге дает правильный вывод для всех тестовых случаев. Ungolfed код:

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
}

Попробуйте онлайн!


Думаю, пробелы после запятых и новой строки после точки с запятой можно убрать.
Эрик Outgolfer

Я считаю 137 байт
Kritixi Lithos

Должно быть, подсчитали спасибо
PunPun1000

Разве вы не можете просто заменить BigDecimal(n)с BigDecimal(n%d), и избавиться от n=n%d?
clismique

Вы можете удалить .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}

х использует 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

х основан на 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

Попробуйте онлайн!

Редактировать:

Откат к исходному решению, как видно из ответа Орджана Йохансена, что оно работает, но я больше не буду играть в гольф


2
If it isn't valid then it should be deleted.
Erik the Outgolfer

as most of the answers so far
Felipe Nardi Batista

@EriktheOutgolfer fixed it...
Felipe Nardi Batista

Do you use 1-indexing?
Erik the Outgolfer


0

Groovy, 55 bytes

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

Explained using 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

Axiom, 71 61 76 bytes

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

n is 0-indexing [0..M]. Test code and result

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