Lấy số thập phân!


23

Bài tập:

Nhiệm vụ của bạn là, khi được đưa ra ba đầu vào:

  • một tử số n
  • mẫu số d
  • một số nguyên khác, x

Tạo một chương trình / hàm tìm xchữ số thứ của số sau vị trí thập phân.

Thông số kỹ thuật:

  • Phạm vi ndlà giữa 12^31 - 1, bao gồm.
  • Phạm vi xlà giữa 110,000,000, bao gồm.
    • Bạn có thể chọn sử dụng lập chỉ mục dựa trên 1 hoặc lập chỉ mục dựa trên 0 cho x. Vui lòng nêu câu trả lời của bạn mà bạn đang sử dụng.
  • ncó thể lớn hơn d.
  • n, dxđược đảm bảo để được nguyên dương (đối với phiên bản chỉ số 1 dựa trên x, nếu bạn chọn để sử dụng lập chỉ mục 0 có trụ sở tại xsau đó xcó thể được 0).
  • Bạn có thể lấy đầu vào theo bất kỳ cách hợp lý nào (Tức là bất kỳ cách nào không phải là lỗ hổng tiêu chuẩn).

Quy tắc:

  • Bạn phải trả về xchữ số thứ chính xác , không phải khi được làm tròn - vì vậy, 15chữ số thứ của 1/6, chẳng hạn, không phải 7, nhưng 6.
  • Chương trình của bạn phải hoạt động cho tất cả xdưới 10 triệu, trừ khi ngôn ngữ của bạn không hỗ trợ số thập phân đến 10 triệu địa điểm.

Ví dụ I / O:

Đầu vào ví dụ sử dụng lập chỉ mục dựa trên 0, có nghĩa là xsẽ đi từ 0đến 9,999,999. Cũng như vậy, "đầu vào" được viết dưới dạng một chuỗi với các khoảng trắng ngăn cách các số.

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
Thử thách này là một tập hợp con của thử thách này
Bassdrop Cumberwubwubwub

8
Tôi cũng không nghĩ đó là một tập hợp con của số Pi, vì nó nói về 1 số vô tỷ cụ thể, vì số này nói về mọi số hữu tỷ
Felipe Nardi Batista


1
@FelipeNardiBatista Hmmm ... Tôi có thể lập luận rằng điều này sẽ ngược lại, vì thử thách này được chỉ định rõ hơn với các phạm vi và nội dung (điều này đã xảy ra trước đây, trong đó một thử thách cũ hơn được đánh dấu là một bản thử thách mới hơn). Tôi không chắc chắn, mặc dù.
clismique

2
Có thể thực hiện bài tập một cách dễ dàng, ngay cả trong một ngôn ngữ không có dấu hiệu ...
RosLuP

Câu trả lời:


12

Python 2 , 25 byte

Cổng câu trả lời Haskell của tôi, vì Python cũng hỗ trợ bignums theo mặc định. Như có, xlà 1 chỉ mục.

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

Hãy thử trực tuyến! (mượn giấy gói của Keerthana Mitchhakaran.)


Rất tuyệt, tôi đã dành vài phút để tự hỏi "nó thực sự rất dễ dàng"? Một cổng tới Ruby sẽ chỉ có 21 byte.
GB

6

Toán học 33 byte

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

Lập chỉ mục 1 dựa trên.

ví dụ: chữ số 10 triệu của Pi bên phải dấu thập phân:

%[Pi,1,10^7]
7

mất khoảng 2 giây trên máy cũ của tôi.

Bạn có thể dùng thử trực tuyến tại WolframAlpha (nhấp vào dấu bằng)



5

PHP> = 7.1, 40 byte

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

bcdiv

Phiên bản trực tuyến


Tôi gặp lỗi này khi chạy mã của bạn:<br /> <b>Notice</b>: Uninitialized string offset: -1 in <b>[...][...]</b> on line <b>6</b><br />
clismique

@ Qwerp-Derp Xin lỗi, bạn cần phiên bản PHP gte 7.1 và trang web sẽ là lần truy cập đầu tiên không thay đổi thành phiên bản cao nhất
Jörg Hülsermann

4

Thạch , 7 byte

⁵*×:ƓDṪ

Hãy thử trực tuyến!

Một chức năng đệ trình (nhưng cũng hoạt động như một chương trình đầy đủ). Các hàm Jelly chỉ có thể lấy hai đối số trực tiếp; do đó tôi lấy chữ số để trả về làm đối số bên trái, tử số làm đối số bên phải và mẫu số từ đầu vào tiêu chuẩn (thay vì sử dụng đối số thứ ba).

Mọi người đã sử dụng Jelly có thể nhận thấy rằng một chương trình đầy đủ có thể mất nhiều hơn hai đối số, nhưng làm như vậy khiến bạn mất quyền truy cập vào cách khó nhất để viết số nguyên 10 không đổi, tương đối phù hợp ở đây. Như vậy, loại đầu vào hỗn hợp này có cảm giác giống như một khai thác hơn là chơi golf thực sự hữu ích; Cá nhân tôi không đồng ý với nó, nhưng quy tắc cho phép điều này hiện tại là +40 / -12, miễn là trong quy tắc đó, tôi cũng có thể khai thác nó (và gần như phải cạnh tranh).

Đối số bên trái của 1 đề cập đến chữ số ngay sau dấu thập phân ("chữ số .1s"), đối số từ 2 đến chữ số .01s, v.v.

Giải trình

⁵*×:Ɠ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 có số học chính xác tùy ý trên các số nguyên, do đó, bằng cách nhân trước với lũy thừa 10, chúng tôi chuyển hiệu quả chữ số chúng tôi muốn sang vị trí đơn vị, nơi dễ dàng trích xuất hơn.


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/.+,//

Hãy thử trực tuyến!

( Xem đầu ra ở dạng thập phân )

Đưa đầu vào vào unary và đầu ra ở unary, và chương trình được lập chỉ mục 1. Rất may, thử thách này này đã chuẩn bị cho tôi cho cái này.

Khái niệm này là tương tự, cả hai thực hiện phân chia dài. Ở đây, tôi thực hiện thời gian phân chia dài x, ở đâux là chữ số sau chữ số thập phân mà tôi phải tìm. Sau mỗi lần lặp, tôi loại bỏ các vị trí thập phân trước đó vì chúng không còn cần thiết nữa.

Trong khi thực hiện phân chia, chương trình có định dạng dividend;divisor;x,result.

s/$/,/ thêm dấu phẩy này, dấu phẩy được yêu cầu để tách kết quả khỏi mọi thứ khác

Sau đó theo vòng lặp chương trình chính

:d nhãn d

  • s/,.+/,/ xóa mọi thứ sau dấu phẩy

  • : nhãn trống

    • s/(1+)(1*;\1;1*,)1{10}?/\21/ thực hiện phép chia, thêm 1 vào kết quả mỗi lần lặp, đồng thời loại bỏ các khối 10 liên tục 1 trong kết quả
  • t nói cách khác, chi nhánh cho nhãn trống, lặp đi lặp lại cho đến khi hết cổ tức

  • s/1*/&&&&&&&&&&/ nhân cổ tức với 10 để chuẩn bị cho lần lặp tiếp theo

  • ta chi nhánh để dán nhãn a

  • :anhãn a, dòng này và dòng trên được yêu cầu để thực hiện tdcông việc

  • s/1,/,/ trừ 1 từ x

tdNhánh có điều kiện thành d, điều này được kích hoạt nếu có sự thay thế thành công kể từ nhánh có điều kiện cuối cùng, vì s/1*/&&&&&&&&&&/luôn luôn thành công, tdsẽ luôn được kích hoạt, nhưng bằng cách giới thiệu nhánh a, chúng tôi sửa nó chỉ phụ thuộc vào sự thay thế trước đó

s/.+,// cuối cùng, loại bỏ mọi thứ trừ kết quả



3

REXX, 76 byte

(Không phải là rất ngắn nhưng nghĩ rằng nó sẽ tạo ra một sự thay đổi để thực hiện một trong REXX) ​​Rexx dựa trên 1 định nghĩa.

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

Giải trình:

  1. Đọc đầu vào cho các số
  2. Đảm bảo đủ chữ số có nghĩa (mặc định là 9)
  3. Tính toán
  4. Chia nhỏ. Tìm dấu thập phân, đếm các ký tự "x", lấy các ký tự sau và đặt vào "z"
  5. In ra chữ số đầu tiên. Pad với 0 để chắc chắn.

Hợp nhất 3 và 4 thực sự làm cho nó dài hơn vì sự thay đổi trong cú pháp:

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

Đối với người không phải REXXers: Chuỗi và số hoàn toàn có thể hoán đổi cho nhau trong REXX. Họ được xác định bằng cách bạn hành động trên chúng. Vì vậy, bạn có thể phân tích một số bằng cách sử dụng các hàm sting mà không cần chuyển đổi. Ví dụ

"27" + "28"

trả về 55 chứ không phải 2728!


Bạn có thể thêm một liên kết đến một thông dịch viên? Tôi tưởng tượng nhiều người dùng không quen thuộc với ngôn ngữ này.
Mego

guidespoint.com/execute_Vxx_online.php Vấn đề duy nhất là tôi không thể tìm ra cách nhập giá trị trong trình thông dịch. Vì vậy, với mục đích thử nghiệm, tôi đã sử dụng các bài tập để đặt các giá trị khi bắt đầu.
theblitz ngày

1
Có vẻ như trình thông dịch đó hoạt động nếu bạn cung cấp đầu vào CLI như thế nào rexx main.rexx 1 2 3. Bạn nên đề cập trong câu trả lời của bạn rằng đầu vào là 1 chỉ mục.
Mego

Không nhận thấy khả năng nhập liệu vì tôi chỉ cần nhấp vào nút thực hiện ở trên cùng. Duh.
theblitz ngày

2

Mẻ, 70 byte

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

@FelipeNardiBatista Làm việc cho tôi khi tôi thử nó.
Neil

2

Lắp ráp ngôn ngữ cpu Intel x86, 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

traslation trong 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

Đối với tham số 'c', phạm vi bắt đầu từ 0; nó sẽ là 0..0xfffffffd. Nếu tham số b = 0 hoặc c nằm ngoài phạm vi 0..0xfffffffd, nó sẽ trả về -1


1

Lua, 42 byte

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

1
Xin chào, và chào mừng đến với PPCG! Đây là một câu trả lời đầu tiên tuyệt vời!
NoOneIsHãy

1

C, 49 43 byte

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

Đối số 'i' là lập chỉ mục 0. Mã kiểm tra và kết quả

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 nhờ vào Erik the Outgolfer, tôi hoàn toàn quên việc nhập khẩu không phải ở trên dòng riêng của họ

-4 byte nhờ Qwerp-Derp để di chuyển n% d đến hàm tạo

-6 byte cảm ơn Kevin Cruijssen vì đã xóa toString ()

Tôi hy vọng đây là cách đếm byte được thực hiện cho các hàm java với nhập khẩu

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

Sử dụng lớp BigDecimal của Java để có được biểu diễn chính xác của khai triển thập phân. Lưu ý rằng đây không phải là mã chạy nhanh nhất từ ​​trước đến nay nhưng cuối cùng nó cũng tạo ra đầu ra chính xác cho tất cả các trường hợp thử nghiệm. Mã bị đánh cắp:

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
}

Hãy thử trực tuyến!


Tôi nghĩ rằng khoảng trắng sau dấu phẩy và dòng mới sau dấu chấm phẩy có thể được loại bỏ.
Erik the Outgolfer

Tôi đếm được 137 byte
Kritixi Lithos

Phải có lời cảm ơn
sai lầm

Bạn không thể thay thế BigDecimal(n)bằng BigDecimal(n%d), và thoát khỏi n=n%d?
clismique

Bạn có thể loại bỏ .toString()và sử dụng +""thay thế (với hai dấu ngoặc đơn bổ sung).
Kevin Cruijssen

1

Clojure, 39 byte

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

hàm ẩn danh với các đối số n,d,xtrong đó xsử dụng một chỉ mục dựa trên.



1

Groovy, 30 byte

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

x sử dụng lập chỉ mục 1.

Giải trình:

{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 dựa trên 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))


Thật không may, giống như giải pháp của tôi, điều này sẽ thất bại với số thập phân dài; thử f(1,7,10000000), ví dụ.
Xù xì

0

Con trăn 2 , 32 byte

Sử dụng chỉ mục 0

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

Hãy thử trực tuyến!

Chỉnh sửa:

Quay trở lại giải pháp ban đầu như đã thấy trong câu trả lời của Ørjan Johansen rằng nó hoạt động, nhưng tôi sẽ không đánh gôn thêm nữa


2
Nếu nó không hợp lệ thì nó sẽ bị xóa.
Erik the Outgolfer

như hầu hết các câu trả lời cho đến nay
Felipe Nardi Batista

@EriktheOutgolfer đã sửa nó ...
Felipe Nardi Batista

Bạn có sử dụng lập chỉ mục 1?
Erik the Outgolfer


0

Groovy, 55 byte

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

Giải thích bằng cách sử dụng 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

Tiên đề, 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 là 0 chỉ mục [0..M]. Mã kiểm tra và kết quả

(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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.