Ottieni il decimale!


23

Compito:

Il tuo compito è, quando ti vengono dati tre input:

  • un numeratore n
  • un denominatore d
  • un altro numero intero, x

Creare un programma / funzione che trova la xcifra del numero dopo il decimale.

Specifiche:

  • L'intervallo di ne dè compreso tra 1e 2^31 - 1, compreso.
  • L'intervallo xè compreso tra 1e 10,000,000, compreso.
    • È possibile scegliere di utilizzare l'indicizzazione in base 1 o l'indicizzazione in base 0 per x. Si prega di indicare nella risposta quale si sta utilizzando.
  • npuò essere più grande di d.
  • n, dE xsono garantiti per essere interi positivi (per la versione indice 1 a base di x, se si sceglie di utilizzare l'indicizzazione 0-based per xallora xpuò essere 0).
  • È possibile accettare input in modo ragionevole (vale a dire in qualsiasi modo che non sia una scappatoia standard).

Regole:

  • È necessario restituire la xcifra esatta , non una volta arrotondata, quindi la 15cifra di 1/6, ad esempio, non lo è 7, ma 6.
  • Il tuo programma deve funzionare per tutti i xmeno di 10 milioni, a meno che la tua lingua non supporti i decimali a 10 milioni di posti.

Esempio I / O:

L'input di esempio utilizza l'indicizzazione basata su 0, il che significa xche andrà da 0a 9,999,999. Inoltre, l '"input" è scritto come una stringa con spazi che separano i numeri.

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
Questa sfida è un sottoinsieme di questa
Bassdrop Cumberwubwubwub

8
Inoltre, non penso che sia un sottoinsieme del Pi, in quanto si parla di 1 numero irrazionale specifico, in quanto questo parla di ogni numero razionale
Felipe Nardi Batista,


1
@FelipeNardiBatista Hmmm ... Potrei sostenere che questo dovrebbe essere il contrario, poiché questa sfida è più specificata con le gamme e le cose (questo è successo prima, in cui una sfida più vecchia è contrassegnata come una copia di una sfida più recente). Non sono sicuro, però.
clismique,

2
È possibile fare l'esercizio, facilmente, anche in una lingua che non ha bignum ...
RosLuP

Risposte:


12

Python 2 , 25 byte

Port of my Haskell answer, dato che Python supporta anche i bignum di default. Come lì, xè 1-indicizzato.

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

Provalo online! (prendendo in prestito l'involucro di Keerthana Prabhakaran.)


Molto bello, ho passato un paio di minuti a chiedermi "è stato davvero così facile"? Una porta per Ruby sarebbe solo 21 byte.
GB

6

Mathematica 33 byte

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

Indicizzazione basata su 1.

es. 10 milionesima cifra di Pi a destra del punto decimale:

%[Pi,1,10^7]
7

impiega circa 2 secondi sulla mia vecchia macchina.

Puoi provarlo online su WolframAlpha (fai clic sul segno di uguale)



5

PHP> = 7.1, 40 byte

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

bcdiv

Versione online


Ricevo questo errore quando <br /> <b>Notice</b>: Uninitialized string offset: -1 in <b>[...][...]</b> on line <b>6</b><br />
eseguo il

@ Qwerp-Derp Mi dispiace che tu abbia bisogno di una versione PHP gte 7.1 e il sito sarà la prima visita a non cambiarla nella versione più
calda

4

Gelatina , 7 byte

⁵*×:ƓDṪ

Provalo online!

Invio di una funzione (ma funziona anche come un programma completo). Le funzioni Jelly possono accettare solo due argomenti direttamente; quindi prendo la cifra per tornare come argomento sinistro, il numeratore come argomento giusto e il denominatore dall'input standard (al posto dell'uso di un terzo argomento).

Le persone abituate a Jelly possono essere consapevoli del fatto che un programma completo può accettare più di due argomenti, ma in tal modo si perde l'accesso al modo più semplice di scrivere il numero intero costante 10, che qui è abbastanza rilevante. In quanto tale, questo tipo di input misti sembra un po 'come un exploit piuttosto che un vero golf utile; Personalmente non sono d'accordo con esso, ma la regola di consentire questo è attualmente a +40 / -12, quindi fintanto che è nelle regole, posso anche sfruttarlo (e praticamente devo essere competitivo).

Un argomento sinistro di 1 si riferisce alla cifra immediatamente dopo il punto decimale (la "cifra .1s"), un argomento di 2 alla cifra .01s e così via.

Spiegazione

⁵*×:Ɠ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 ha un'aritmetica di precisione arbitraria sugli interi, quindi pre-moltiplicando per una potenza di 10, stiamo effettivamente spostando la cifra che vogliamo nella posizione delle unità, dove è molto più facile estrarre.


4

sed -r , 93 131 136 byte

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

Provalo online!

( Vedi output in decimale )

Accetta input in unario e output in unario e il programma è 1 indicizzato. Per fortuna, questa sfida mi ha già preparato per questo.

Il concetto è simile, entrambi implementano una lunga divisione. Qui, eseguo lunghi xtempi di divisione , dovex è la cifra dopo il decimale che devo trovare. Dopo ogni iterazione, scarto le posizioni decimali precedenti perché non sono più necessarie.

Durante la divisione, il programma è nel formato dividend;divisor;x,result.

s/$/,/ aggiunge questa virgola, la virgola è necessaria per separare il risultato da tutto il resto

Quindi segue il ciclo principale del programma

:d etichetta d

  • s/,.+/,/ rimuovi tutto dopo la virgola

  • : etichetta vuota

    • s/(1+)(1*;\1;1*,)1{10}?/\21/ esegue la divisione, aggiungendo 1 al risultato ogni iterazione, rimuovendo contemporaneamente blocchi di 10 1 continui nel risultato
  • t ramo all'etichetta vuota, in altre parole, ciclo fino a quando il dividendo è stato esaurito

  • s/1*/&&&&&&&&&&/ moltiplicare il dividendo per 10 per preparare la prossima iterazione

  • ta ramo per etichettare a

  • :aetichetta a, questa linea e la linea sopra sono necessarie per far tdfunzionare

  • s/1,/,/ sottrai 1 da x

tdRamo condizionale a d, questo viene attivato se c'è stata una sostituzione riuscita dall'ultimo ramo condizionale, poiché ha s/1*/&&&&&&&&&&/sempre successo, tdverrà sempre attivato, ma introducendo il ramo a, lo risolviamo in modo che dipenda solo dalla sostituzione precedente

s/.+,// infine, rimuovi tutto tranne il risultato



3

REXX, 76 byte

(Non molto breve ma ho pensato che sarebbe stato un cambiamento fare uno in REXX) ​​Rexx è basato su 1 per definizione.

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

Spiegazione:

  1. Leggi input ai numeri
  2. Garantire cifre abbastanza significative (il valore predefinito è 9)
  3. Calcolare
  4. Diviso. Trova il punto decimale, conta i caratteri "x" in avanti, prendi i seguenti caratteri e inserisci "z"
  5. Stampa la prima cifra. Pad con 0 per essere sicuri.

L'unione di 3 e 4 in realtà lo rende più lungo a causa della modifica della sintassi:

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

Per i non-REXX: stringhe e numeri sono totalmente intercambiabili in REXX. Sono determinati dal modo in cui agisci su di loro. Quindi puoi analizzare un numero usando le funzioni di puntura senza conversione. Per esempio

"27" + "28"

restituisce 55 e non 2728!


Potresti aggiungere un link a un interprete? Immagino che molti utenti non abbiano familiarità con questa lingua.
Mego

tutorialspoint.com/execute_rexx_online.php L' unico problema è che non sono riuscito a capire come inserire valori nell'interprete. Quindi, a scopo di test, ho usato le assegnazioni per impostare i valori all'inizio.
theblitz,

1
Sembra che l'interprete funzioni se dai un input CLI simile rexx main.rexx 1 2 3. Dovresti menzionare nella tua risposta che l'input è 1-indicizzato.
Mego

Non ho notato la possibilità di input perché ho appena fatto clic sul pulsante di esecuzione in alto. Duh.
theblitz,

2

Lotto, 70 byte

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

@FelipeNardiBatista Ha funzionato per me quando l'ho provato.
Neil,

2

Assembly linguaggio Intel x86 cpu, 50 byte

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

traslazione in 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

Per il parametro 'c' l'intervallo inizia da 0; sarebbe 0..0xfffffffd. Se i parametri b = 0 o c fuori dall'intervallo 0..0xfffffffd restituirebbe -1


1

Lua, 42 byte

function a(n,x,d)
print((n*10^x/d)%10)
end

1
Ciao e benvenuto in PPCG! Questa è un'ottima prima risposta!
NoOneIsHere

1

C, 49 43 byte

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

L'argomento 'i' è indicizzazione 0. Codice test e risultato

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 122 byte

-3 byte grazie a Erik the Outgolfer, ho completamente dimenticato che le importazioni non dovevano essere sulla loro linea

-4 byte grazie a Qwerp-Derp per lo spostamento di n% d nel costruttore

-6 byte grazie Kevin Cruijssen per aver rimosso toString ()

Spero che sia così che viene eseguito il conteggio dei byte per le funzioni Java con le importazioni

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

Utilizza la classe BigDecimal di Java per ottenere la rappresentazione esatta dell'espansione decimale. Nota che non è il codice più veloce mai eseguito ma alla fine produce l'output corretto per tutti i casi di test. Codice non golfato:

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
}

Provalo online!


Penso che gli spazi dopo le virgole e la nuova riga dopo il punto e virgola possano essere rimossi.
Erik the Outgolfer,

Conto 137 byte
Kritixi Lithos il

Devo aver
contato male

Non puoi semplicemente sostituirlo BigDecimal(n)con BigDecimal(n%d), e sbarazzarsi del n=n%d?
clismique,

È possibile rimuovere .toString()e utilizzare +""invece (con due parentesi aggiuntive).
Kevin Cruijssen,

1

Clojure, 39 byte

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

funzione anonima con argomenti in n,d,xcui xutilizza una indicizzazione basata.



1

Groovy, 30 byte

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

x utilizza 1 indicizzazione basata.

Spiegazione:

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

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

x è basato su 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))


Sfortunatamente, come la mia soluzione, questo fallirà con decimali lunghi; prova f(1,7,10000000), per esempio.
Shaggy,

0

Python 2 , 32 byte

Utilizza l'indicizzazione 0

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

Provalo online!

Modificare:

Eseguito il rollback alla soluzione originale come si vede nella risposta di Ørjan Johansen che funziona, ma non lo farò più


2
Se non è valido, dovrebbe essere eliminato.
Erik the Outgolfer,

come la maggior parte delle risposte finora
Felipe Nardi Batista,

@EriktheOutgolfer ha risolto il problema ...
Felipe Nardi Batista,

Usi l'indicizzazione 1?
Erik the Outgolfer


0

Groovy, 55 byte

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

Spiegato usando 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 byte

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

n è indicizzazione 0 [0..M]. Codice test e risultato

(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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.