Holen Sie sich die Dezimalzahl!

23

Aufgabe:

Ihre Aufgabe ist es, wenn Sie drei Eingaben erhalten:

  • ein Zähler n
  • ein Nenner d
  • eine andere ganze Zahl, x

Erstellen Sie ein Programm / eine Funktion, die die xdritte Stelle der Zahl nach der Dezimalstelle findet.

Technische Daten:

  • Der Bereich von nund dliegt zwischen 1und 2^31 - 1, einschließlich.
  • Der Bereich von xliegt zwischen 1und 10,000,000einschließlich.
    • Sie können wählen, ob 1-basierte Indizierung oder 0-basierte Indizierung für verwendet werden soll x. Bitte geben Sie in Ihrer Antwort an, welche Sie verwenden.
  • nkann größer sein als d.
  • n, dund xsind garantiert positive ganze Zahlen (für 1-basierte Index-Version von x, wenn Sie 0-basierte Indexierung für xdann xverwenden möchten, kann sein 0).
  • Sie können Eingaben auf jede vernünftige Weise vornehmen (dh auf jede Art und Weise, die keine Standardlücke darstellt).

Regeln:

  • Sie müssen die exakte xZiffer zurückgeben, nicht wenn sie gerundet ist - also ist die z. B. 15zehnte Ziffer 1/6nicht 7, aber 6.
  • Ihr Programm muss für alle xunter 10 Millionen funktionieren, es sei denn, Ihre Sprache unterstützt keine Dezimalstellen von 10 Millionen Stellen.

Beispiel I / O:

Die Beispieleingabe verwendet eine 0-basierte Indizierung, dh, es xwird von 0nach gewechselt 9,999,999. Außerdem wird die "Eingabe" als Zeichenfolge mit Leerzeichen zwischen den Zahlen geschrieben.

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
Clismique
quelle
2
Diese Herausforderung ist eine Teilmenge dieser
Bassdrop Cumberwubwubwub
8
Ich denke auch nicht, dass es sich um eine Teilmenge der Pi handelt, da diese von einer bestimmten irrationalen Zahl handelt, wie diese von jeder rationalen Zahl
Felipe Nardi Batista,
1
@FelipeNardiBatista Hmmm ... Ich könnte argumentieren, dass dies umgekehrt sein sollte, da diese Herausforderung mehr mit den Bereichen und Sachen spezifiziert ist (dies ist zuvor geschehen, wo eine ältere Herausforderung als Duplikat einer neueren Herausforderung markiert ist). Ich bin mir aber nicht sicher.
Clismique
2
Es ist möglich, die Übung leicht zu machen, auch in einer Sprache, die kein Bignum hat ...
RosLuP

Antworten:

12

Python 2 , 25 Bytes

Port meiner Haskell-Antwort, da Python standardmäßig auch Bignums unterstützt. Wie dort xist 1-indiziert.

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

Probieren Sie es online! (Keerthana Prabhakarans Umschlag ausleihen.)

Ørjan Johansen
quelle
Sehr schön, ich habe mich ein paar Minuten lang gefragt, ob es wirklich so einfach ist. Ein Port zu Ruby wäre nur 21 Bytes.
GB
6

Mathematica 33 Bytes

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

1-basierte Indizierung.

zB 10-millionste Stelle von Pi rechts vom Dezimalpunkt:

%[Pi,1,10^7]
7

dauert auf meinem alten Rechner ca. 2 Sekunden.

Du kannst es online bei WolframAlpha ausprobieren (klicke auf das Gleichheitszeichen)

Kelly Lowder
quelle
6

Haskell , 26 Bytes

Funktioniert für alle Testfälle. Yay Bignums!

(n#d)xnimmt Integers und gibt ein zurückInteger . xist 1-indiziert.

(n#d)x=n*10^x`div`d`mod`10

Probieren Sie es online!

Ørjan Johansen
quelle
5

PHP> = 7.1, 40 Bytes

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

bcdiv

Online Version

Jörg Hülsermann
quelle
Ich <br /> <b>Notice</b>: Uninitialized string offset: -1 in <b>[...][...]</b> on line <b>6</b><br />
erhalte
@ Qwerp-Derp Sorry du brauchst eine PHP Version gte 7.1 und die Seite wird es beim ersten Besuch nicht ändern auf die höchste Version
Jörg Hülsermann
4

Gelee , 7 Bytes

⁵*×:ƓDṪ

Probieren Sie es online!

Eine Funktionsübermittlung (funktioniert aber auch als Vollprogramm). Jelly-Funktionen können nur zwei Argumente direkt übernehmen. Daher nehme ich die Ziffer als linkes Argument, den Zähler als rechtes Argument und den Nenner aus der Standardeingabe (anstelle eines dritten Arguments).

Menschen, die an Jelly gewöhnt sind, sind sich vielleicht bewusst, dass ein vollständiges Programm mehr als zwei Argumente enthalten kann. Dadurch verlieren Sie jedoch den Zugriff auf die genaueste Methode zum Schreiben der konstanten Ganzzahl 10, die hier ziemlich relevant ist. Insofern fühlt sich diese Art von gemischtem Input eher wie ein Exploit an als wie nützliches Golfen. Ich persönlich bin damit nicht einverstanden, aber die Regel, dies zuzulassen, liegt derzeit bei +40 / -12. Solange sie in den Regeln enthalten ist, kann ich sie genauso gut ausnutzen (und muss ziemlich konkurrenzfähig sein).

Ein linkes Argument von 1 bezieht sich auf die Ziffer unmittelbar nach dem Dezimalpunkt (die ".1s-Ziffer"), ein Argument von 2 auf die .01s-Ziffer und so weiter.

Erläuterung

⁵*×:Ɠ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 hat eine Arithmetik mit willkürlicher Genauigkeit für ganze Zahlen. Durch Vormultiplizieren mit einer Potenz von 10 verschieben wir die gewünschte Ziffer effektiv an die Position der Einheit, an der sie viel einfacher zu extrahieren ist.


quelle
4

sed -r , 93 131 136 Bytes

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

Probieren Sie es online!

( Siehe Ausgabe in Dezimal )

Nimmt Eingaben in Unary und Ausgaben in Unary auf, und das Programm ist 1-indiziert. Zum Glück das hat mich Herausforderung bereits auf diese vorbereitet.

Das Konzept ist ähnlich, beide implementieren lange Teilung. Hier führe ich lange Teilungen durchx , wox sich die Stelle nach der Dezimalstelle befindet, die ich finden muss. Nach jeder Iteration verwerfe ich die vorherigen Dezimalstellen, da sie nicht mehr benötigt werden.

Während des Aufteilens hat das Programm das Format dividend;divisor;x,result.

s/$/,/ Fügt man dieses Komma hinzu, wird das Komma benötigt, um das Ergebnis von allem anderen zu trennen

Dann folgt die Hauptprogrammschleife

:d Etikett d

  • s/,.+/,/ alles nach dem Komma entfernen

  • : leeres Etikett

    • s/(1+)(1*;\1;1*,)1{10}?/\21/ Führen Sie eine Division durch, indem Sie dem Ergebnis bei jeder Iteration 1 hinzufügen und gleichzeitig Blöcke mit 10 fortlaufenden Einsen im Ergebnis entfernen
  • t verzweige zum leeren Etikett, sprich Schleife, bis die Dividende erschöpft ist

  • s/1*/&&&&&&&&&&/ Multiplizieren Sie die Dividende mit 10, um sich auf die nächste Iteration vorzubereiten

  • ta Abzweig zur Bezeichnung a

  • :abeschriften Sie a, diese Linie und die Linie oben werden angefordert, um tdArbeit zu bilden

  • s/1,/,/ subtrahiere 1 von x

tdbedingte Verzweigung nach d, wird ausgelöst, wenn seit der letzten bedingten Verzweigung eine erfolgreiche Substitution stattgefunden hat, da diese s/1*/&&&&&&&&&&/immer erfolgreich ist. tdDurch die Einführung der Verzweigung a wird dies jedoch behoben, so dass es nur von der vorherigen Substitution abhängt

s/.+,// Entfernen Sie schließlich alles außer dem Ergebnis

Kritixi Lithos
quelle
3

REXX, 76 Bytes

(Nicht sehr kurz, aber ich dachte, es würde eine Änderung in REXX bedeuten) Rexx ist per Definition 1-basiert.

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

Erläuterung:

  1. Eingabe zu den Zahlen lesen
  2. Genügend signifikante Ziffern garantieren (Standard ist 9)
  3. Berechnung
  4. Teilt. Suchen Sie den Dezimalpunkt, zählen Sie vorwärts "x" Zeichen, nehmen Sie die folgenden Zeichen und setzen Sie in "z"
  5. Erste Ziffer ausdrucken. Mit 0 auffüllen, um sicherzugehen.

Das Zusammenführen von 3 und 4 verlängert sich aufgrund der geänderten Syntax:

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

Für Nicht-REXXer: Zeichenfolgen und Zahlen sind in REXX vollständig austauschbar. Sie werden dadurch bestimmt, wie Sie auf sie einwirken. Sie können also eine Zahl mit Stichfunktionen ohne Konvertierung analysieren. Beispielsweise

"27" + "28"

gibt 55 und nicht 2728 zurück!

der Blitz
quelle
Könnten Sie einen Link zu einem Dolmetscher hinzufügen? Ich würde mir vorstellen, dass viele Benutzer mit dieser Sprache nicht vertraut sind.
Mego
Das einzige Problem ist, dass ich nicht herausfinden konnte, wie man Werte in den Interpreter eingibt. Zu Testzwecken habe ich Zuweisungen verwendet, um die Werte zu Beginn festzulegen.
Theblitz
1
Es sieht so aus, als ob der Interpreter funktioniert, wenn Sie eine CLI-Eingabe wie geben rexx main.rexx 1 2 3. Sie sollten in Ihrer Antwort erwähnen, dass die Eingabe 1-indiziert ist.
Mego
Die Eingabemöglichkeit ist mir nicht aufgefallen, da ich oben einfach auf die Schaltfläche Ausführen geklickt habe. Duh.
Theblitz
2

Batch, 70 Bytes

@set n=%1
@for /l %%x in (0,1,%3)do @set/an=n%%%2*10
@cmd/cset/an/%2
Neil
quelle
@FelipeNardiBatista Hat für mich gearbeitet, als ich es ausprobiert habe.
Neil
2

Assembly Intel x86-CPU-Sprache, 50 Bytes

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

Übersetzung 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

Für den Parameter 'c' beginnt der Bereich bei 0; es wäre 0..0xfffffffd. Wenn die Parameter b = 0 oder c außerhalb des Bereichs 0..0xfffffffd liegen, wird -1 zurückgegeben

RosLuP
quelle
1

Lua, 42 Bytes

function a(n,x,d)
print((n*10^x/d)%10)
end
Connor Belli
quelle
1
Hallo und willkommen bei PPCG! Dies ist eine großartige erste Antwort!
NoOneIsHere
1

C 49 43 Bytes

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

Das Argument 'i' ist eine 0-Indizierung. Testcode und Ergebnis

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 
RosLuP
quelle
1

Java 7, 146 139 137 133 128 122 Bytes

-3 Bytes dank Erik the Outgolfer, ich habe total vergessen, dass Importe nicht in einer eigenen Zeile sein müssen

-4 Byte dank Qwerp-Derp für das Verschieben von n% d in den Konstruktor

-6 Bytes danke Kevin Cruijssen für das Entfernen des toString ()

Ich hoffe, so wird die Byte-Zählung für Java-Funktionen mit Importen durchgeführt

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

Verwendet die BigDecimal-Klasse von Java, um eine genaue Darstellung der Dezimalerweiterung zu erhalten. Beachten Sie, dass es sich nicht um den schnellsten Code handelt, der jemals ausgeführt wurde, aber letztendlich für alle Testfälle die richtige Ausgabe liefert. Ungolfed-Code:

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
}

Probieren Sie es online!

PunPun1000
quelle
Ich denke, die Leerzeichen nach den Kommas und die Zeilenumbrüche nach dem Semikolon können entfernt werden.
Erik der Outgolfer
Ich zähle 137 Bytes
Kritixi Lithos
Muss falsch gezählt haben, danke
PunPun1000
Sie können nicht ersetzen Sie einfach BigDecimal(n)mit BigDecimal(n%d), und werde das los n=n%d?
Clismique
Sie können das entfernen .toString()und +""stattdessen verwenden (mit zwei zusätzlichen Klammern).
Kevin Cruijssen
1

Clojure, 39 Bytes

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

anonyme Funktion mit Argumenten n,d,xwox eine einseitige Indizierung verwendet wird.

Matias Bjarland
quelle
1

F # (.NET Core) , 30 Byte

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

Probieren Sie es online!

(1-basierte Indizierung verwenden)

Nur ein weiterer Metaprogrammierer
quelle
Ich zähle 33 Bytes. Ich würde auch vorschlagen, ein Try it Online! Verknüpfung.
Wastl
Ich hatte die falsche Funktion in meiner Zwischenablage. Vielen Dank.
Nur ein weiterer Metaprogrammierer
1

Groovy, 30 Bytes

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

x verwendet eine 1-basierte Indizierung.

Erläuterung:

{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
}
Matias Bjarland
quelle
0

Ruby, 39 Bytes

->n,m,o{(n*1.0/m).to_s.split(?.)[1][o]}
dkudriavtsev
quelle
0

JavaScript (ES6), 34 Byte

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

x ist 0-basiert

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

Weedoze
quelle
Leider schlägt dies, wie meine Lösung, mit langen Dezimalstellen fehl. versuchen Sie es f(1,7,10000000)zum Beispiel.
Shaggy
0

Python 2 , 32 Bytes

Verwendet die 0-Indizierung

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

Probieren Sie es online!

Bearbeiten:

Zurück zur ursprünglichen Lösung, wie in Ørjan Johansens Antwort zu sehen, dass es funktioniert, aber ich werde nicht weiter Golf spielen

Felipe Nardi Batista
quelle
2
Wenn es nicht gültig ist, sollte es gelöscht werden.
Erik der Outgolfer
Wie die meisten Antworten bisher
Felipe Nardi Batista
@EriktheOutgolfer behoben ...
Felipe Nardi Batista
Verwenden Sie die 1-Indizierung?
Erik der Outgolfer
0

Groovy, 55 Bytes

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

Erklärt mit 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.
}
Magische Kraken-Urne
quelle
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 ist 0-Indizierung [0..M]. Testcode und Ergebnis

(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
RosLuP
quelle