Zdobądź przecinek dziesiętny!


23

Zadanie:

Twoim zadaniem jest podanie trzech danych wejściowych:

  • licznik n
  • mianownik d
  • inna liczba całkowita, x

Utwórz program / funkcję, która znajdzie xdziesiątą cyfrę po przecinku.

Okular:

  • Zakres ni djest pomiędzy 1i 2^31 - 1włącznie.
  • Zakres xwynosi od 1i 10,000,000włącznie.
    • Możesz wybrać indeksowanie 1 lub 0 x. Podaj w swojej odpowiedzi, którego używasz.
  • nmoże być większy niż d.
  • n, dI xsą gwarancją całkowite dodatnie (dla wersji indeksu 1 opartej x, jeśli zdecydujesz się skorzystać 0 indeksowanie oparte na xczym xmoże być 0).
  • Możesz przyjmować dane wejściowe w dowolny rozsądny sposób (tj. W dowolny sposób, który nie jest standardową luką).

Zasady:

  • Musisz zwrócić dokładną xcyfrę th, nie po zaokrągleniu - więc np. 15Cyfra th 1/6nie jest 7, ale 6.
  • Twój program musi działać dla wszystkich xponiżej 10 milionów, chyba że Twój język nie obsługuje miejsc dziesiętnych do 10 milionów miejsc.

Przykład I / O:

W przykładowym danych wejściowych zastosowano indeksowanie oparte na 0, co oznacza, że xnastąpi przejście od 0do 9,999,999. Oprócz tego „wejście” zapisywane jest jako ciąg znaków ze spacjami oddzielającymi liczby.

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
To wyzwanie jest podzbiorem tego
wyzwania

8
Nie sądzę też, aby był to podzbiór liczby Pi, ponieważ mówi ona o 1 konkretnej liczbie niewymiernej, ponieważ ta mówi o każdej liczbie wymiernej
Felipe Nardi Batista


1
@FelipeNardiBatista Hmmm ... Mogę argumentować, że powinno być odwrotnie, ponieważ wyzwanie to jest bardziej określone z zakresami i innymi rzeczami (zdarzyło się to wcześniej, gdy starsze wyzwanie jest oznaczone jako duplikat nowszego wyzwania). Nie jestem jednak pewien.
clismique

2
Ćwiczenie można wykonać łatwo, nawet w języku, w którym nie ma bignum ...
RosLuP

Odpowiedzi:


12

Python 2 , 25 bajtów

Port mojej odpowiedzi Haskell, ponieważ Python domyślnie obsługuje również bignum. Tam xjest 1-indeksowany.

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

Wypróbuj online! (pożyczanie opakowania Keerthany Prabhakaran).


Bardzo miło, spędziłem kilka minut zastanawiając się „czy to naprawdę takie proste”? Port do Ruby miałby tylko 21 bajtów.
GB

6

Mathematica 33 bajtów

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

Indeksowanie 1.

np. 10-milionowa cyfra Pi po przecinku:

%[Pi,1,10^7]
7

na mojej starej maszynie zajmuje około 2 sekund.

Możesz spróbować online w WolframAlpha (kliknij znak równości)




4

Galaretka , 7 bajtów

⁵*×:ƓDṪ

Wypróbuj online!

Przesyłanie funkcji (ale działa również jako pełny program). Funkcje galaretki mogą przyjmować tylko dwa argumenty bezpośrednio; dlatego zwracam cyfrę jako lewy argument, licznik jako prawy argument i mianownik ze standardowego wejścia (zamiast używania trzeciego argumentu).

Ludzie przyzwyczajeni do Galaretki mogą być świadomi, że pełny program może przyjąć więcej niż dwa argumenty, ale powoduje to utratę dostępu do najkrótszego sposobu na zapisanie stałej liczby całkowitej 10, co jest tutaj dość istotne. W związku z tym tego rodzaju mieszane dane wejściowe wydają się być raczej exploitem niż faktycznym golfem; Ja osobiście się z tym nie zgadzam, ale zasada na to pozwala obecnie na +40 / -12, więc tak długo, jak to jest w zasadach, równie dobrze mogę to wykorzystać (i właściwie muszę być konkurencyjny).

Lewy argument 1 odnosi się do cyfry bezpośrednio po przecinku („cyfra .1s”), argument 2 do cyfry .01s i tak dalej.

Wyjaśnienie

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

Galaretka ma arytmetykę o dowolnej precyzji na liczbach całkowitych, więc pomnożenie wstępne przez potęgę 10 skutecznie przenosi cyfrę, którą chcemy, do pozycji jednostek, gdzie jest znacznie łatwiej wyodrębnić.


4

sed -r , 93 131 136 bajtów

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

Wypróbuj online!

( Patrz dane wyjściowe w postaci dziesiętnej )

Pobiera dane wejściowe w jednostkowej i wyjściowe w jednostkowej, a program ma indeks 1. Na szczęście to wyzwanie przygotowało mnie już do tego.

Koncepcja jest podobna, oba wdrażają długi podział. Tutaj wykonuję długi xczas podziału , gdzie xjest cyfra po przecinku, który muszę znaleźć. Po każdej iteracji odrzucam poprzednie miejsca po przecinku, ponieważ nie są już potrzebne.

Podczas podziału program ma format dividend;divisor;x,result.

s/$/,/ dodaje ten przecinek, przecinek jest wymagany do oddzielenia wyniku od wszystkiego innego

Następnie następuje główna pętla programu

:d etykieta d

  • s/,.+/,/ usuń wszystko po przecinku

  • : pusta etykieta

    • s/(1+)(1*;\1;1*,)1{10}?/\21/ wykonaj podział, dodając 1 do wyniku każdej iteracji, jednocześnie usuwając bloki 10 ciągłych 1s w wyniku
  • t rozgałęzić się do pustej etykiety, innymi słowy, zapętlić, aż dywidenda zostanie wyczerpana

  • s/1*/&&&&&&&&&&/ pomnóż dywidendę przez 10, aby przygotować się do następnej iteracji

  • ta gałąź, aby oznaczyć a

  • :aetykieta a, ta linia i powyższa linia są wymagane do tddziałania

  • s/1,/,/ odejmij 1 od x

tdgałąź warunkowa do d, jest to wyzwalane, jeśli nastąpiło pomyślne podstawienie od ostatniej gałęzi warunkowej, ponieważ s/1*/&&&&&&&&&&/zawsze jest udane, tdzawsze zostanie uruchomione, ale wprowadzając gałąź a, naprawiamy to, aby zależało to tylko od poprzedniego podstawienia

s/.+,// na koniec usuń wszystko oprócz wyniku



3

REXX, 76 bajtów

(Niezbyt krótki, ale sądził, że zmieniłoby się, aby zrobić jedną w REXX) ​​Rexx opiera się na 1 z definicji.

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

Wyjaśnienie:

  1. Przeczytaj dane wejściowe do liczb
  2. Zapewnij wystarczającą liczbę cyfr znaczących (domyślnie 9)
  3. Obliczać
  4. Rozdzielać. Znajdź przecinek dziesiętny, policz do przodu znaki „x”, weź następujące znaki i wstaw do „z”
  5. Wydrukuj pierwszą cyfrę. Dla pewności wpisz 0.

Połączenie 3 i 4 faktycznie wydłuża go z powodu zmiany składni:

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

Dla nie-REXX-ów: ciągi i liczby są całkowicie wymienne w REXX. Są one zdeterminowane tym, jak na nich postępujesz. Możesz więc parsować liczbę za pomocą funkcji żądła bez konwersji. Na przykład

"27" + "28"

zwraca 55, a nie 2728!


Czy możesz dodać link do tłumacza? Wyobrażam sobie, że wielu użytkowników nie zna tego języka.
Mego

tutorialspoint.com/execute_rexx_online.php Jedynym problemem jest to, że nie mogłem wymyślić, jak wprowadzić wartości w interpreter. Więc do celów testowych użyłem przypisań, aby ustawić wartości na początku.
theblitz,

1
Wygląda na to, że ten interpreter działa, jeśli podasz dane wejściowe CLI rexx main.rexx 1 2 3. Powinieneś wspomnieć w swojej odpowiedzi, że dane wejściowe mają indeks 1.
Mego

Nie zauważyłem możliwości wprowadzania danych, ponieważ właśnie kliknąłem przycisk wykonania u góry. Duh.
theblitz,

2

Partia, 70 bajtów

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

@FelipeNardiBatista Pracował dla mnie, kiedy go wypróbowałem.
Neil

2

Asembler języka procesora Intel x86, 50 bajtów

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

tłumaczenie w nasm

; 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

Dla parametru „c” zakres zaczyna się od 0; byłoby 0..0xfffffffd. Jeśli parametry b = 0 lub c poza zakresem 0..0xfffffffd zwróci -1



1

C, 49 43 bajtów

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

Argument „i” oznacza indeksowanie 0. Testuj kod i wynik

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

Java 7, 146 139 137 133 128 128 122 bajtów

-3 bajty dzięki Erikowi Outgolferowi, całkowicie zapomniałem, że importowanie nie musiało odbywać się we własnej linii

-4 bajty dzięki Qwerp-Derp za przeniesienie n% d do konstruktora

-6 bajtów dzięki Kevin Cruijssen za usunięcie toString ()

Mam nadzieję, że w ten sposób wykonywana jest liczba bajtów dla funkcji Java z importami

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

Używa klasy BigDecimal Java, aby uzyskać dokładną reprezentację rozwinięcia dziesiętnego. Zauważ, że nie jest to najszybciej działający kod, ale ostatecznie generuje poprawne dane wyjściowe dla wszystkich przypadków testowych. Nieskluczony kod:

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
}

Wypróbuj online!


Myślę, że można usunąć spacje po przecinkach i znak nowej linii po średniku.
Erik the Outgolfer

Liczę 137 bajtów
Kritixi Lithos


Nie można po prostu wymienić BigDecimal(n)się BigDecimal(n%d)i pozbyć się n=n%d?
clismique

Możesz usunąć .toString()i użyj +""zamiast tego (z dwoma dodatkowymi nawiasami).
Kevin Cruijssen

1

Clojure, 39 bajtów

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

anonimowa funkcja z argumentami, w n,d,xktórej xwykorzystuje się indeksowanie oparte na jednym.



1

Groovy, 30 bajtów

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

x używa indeksowania 1.

Wyjaśnienie:

{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 bajty

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

x jest oparty na 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))


Niestety, podobnie jak moje rozwiązanie, nie uda się to z długimi miejscami po przecinku; spróbuj f(1,7,10000000)na przykład.
Kudłaty

0

Python 2 , 32 bajty

Wykorzystuje indeksowanie 0

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

Wypróbuj online!

Edytować:

Wróciłem do oryginalnego rozwiązania, jak widać w odpowiedzi Ørjana Johansena, że ​​działa, ale nie będę go więcej grał w golfa


2
Jeśli nie jest prawidłowy, należy go usunąć.
Erik the Outgolfer

jak większość dotychczasowych odpowiedzi
Felipe Nardi Batista

@EriktheOutgolfer naprawił to ...
Felipe Nardi Batista

Czy korzystasz z indeksowania 1?
Erik the Outgolfer


0

Groovy, 55 bajtów

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

Wyjaśnione przy użyciu 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 bajtów

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

n oznacza indeksowanie 0 [0..M]. Testuj kod i wynik

(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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.