Tìm số thập phân thứ n của số pi


33

Đã có 30 thử thách dành riêng cho pi nhưng không một thử thách nào yêu cầu bạn tìm số thập phân thứ n, vì vậy ...

Thử thách

Đối với bất kỳ số nguyên nào trong phạm vi 0 <= n <= 10000hiển thị thập phân thứ n của pi.

Quy tắc

  • Số thập phân là mỗi số sau 3.
  • Chương trình của bạn có thể là một chức năng, hoặc một chương trình đầy đủ
  • Bạn phải xuất kết quả trong cơ sở 10
  • Bạn có thể nhận được ntừ bất kỳ phương thức nhập phù hợp nào (stdin, input (), tham số hàm, ...), nhưng không được mã hóa cứng
  • Bạn có thể sử dụng lập chỉ mục dựa trên 1 nếu đó là ngôn ngữ bạn chọn
  • Bạn không cần phải đối phó với đầu vào không hợp lệ ( n == -1, n == 'a'hay n == 1.5)
  • Nội dung được phép, nếu chúng hỗ trợ tối thiểu 10 nghìn số thập phân
  • Thời gian chạy không thành vấn đề, vì đây là về mã ngắn nhất và không phải là mã nhanh nhất
  • Đây là , mã ngắn nhất tính bằng byte thắng

Các trường hợp thử nghiệm

f(0)     == 1
f(1)     == 4 // for 1-indexed languages f(1) == 1
f(2)     == 1 // for 1-indexed languages f(2) == 4
f(3)     == 5
f(10)    == 8
f(100)   == 8
f(599)   == 2
f(760)   == 4
f(1000)  == 3
f(10000) == 5

Để tham khảo, đây là 100 chữ số đầu tiên của pi.


Được xây dựng trong? ví dụstr(pi())[n+2]
primo

6
Các mục tiêu dupe gần nhất IMO là Tính toán tổng số chữ số bị cắt (làm quá tải tham số hoặc nó sẽ chỉ là một sự khác biệt hữu hạn được áp dụng cho thử thách này), Truyền chính xác pi (thêm chỉ mục và loại bỏ một số in) và mã hóa cửa sổ Pi .
Peter Taylor

3
@Suever ofcference! Quy tắc đó chỉ để chỉ ra rằng 10k là mức tối thiểu mà chương trình của bạn có thể xử lý
Bassdrop Cumberwubwubwub

4
Tôi đề nghị thêm f (599) vào các trường hợp thử nghiệm, vì có thể dễ dàng hiểu sai (bạn cần khoảng 3 số thập phân chính xác thêm).
aditsu

2
Ngoài ra f (760) = 4, bắt đầu chuỗi 4 999999 8, dễ dàng làm tròn không chính xác.
Anders Kaseorg

Câu trả lời:


22

05AB1E, 3 byte

žs¤

Giải thích

žs   # push pi to N digits
  ¤  # get last digit

Dùng thử trực tuyến

Sử dụng lập chỉ mục 1 dựa trên.
Hỗ trợ lên tới 100k chữ số.


Pi đến n chữ số không tròn?
busukxuan

7
@busukxuan Không. Nó đã sử dụng hằng số được xác định trước từ pi đến 100k chữ số và lấy N của chúng.
Emigna

4
@Emigna Điều đó rất tiện dụng. Giải pháp tốt.
Suever

2
Ngắn và sắc nét, PCG ở mức tốt nhất
Xylius

16

Python 2, 66 byte

n=input()+9
x=p=5L**7
while~-p:x=p/2*x/p+10**n;p-=2
print`x/5`[-9]

Đầu vào được lấy từ stdin.


Sử dụng mẫu

$ echo 10 | python pi-nth.py
8

$ echo 100 | python pi-nth.py
8

$ echo 1000 | python pi-nth.py
3

$ echo 10000 | python pi-nth.py
5

Hãy cẩn thận về việc sử dụng n trong thuật toán ... đầu ra cho 599 phải là 2 chứ không phải 1. Ngoài ra, bạn có thể muốn chỉ định rằng bạn đang sử dụng python 2.
aditsu

@aditsu cập nhật. Khẳng định cho tất cả n ≤ 1000 .
Primo

1
Nếu bạn chọn nlàm đầu vào cộng với 9, bạn có thể tránh được parens.
xnor

@xnor d'oh. Cảm ơn;)
primo

2
Một vài chữ số đầu tiên được tạo bởi thuật toán này là '3.141596535897932' 'thiếu' 2 'giữa các vị trí 5 và 6. Tại sao? Bởi vì đó là khi toán tử `` của Python 2 bắt đầu nối thêm một Lchuỗi.
Anders Kaseorg

11

Bash + coreutils, 60 49 byte

echo "scale=10100;4*a(1)"|bc -l|tr -d '\\\n'|cut -c$(($1+2))

bc -l<<<"scale=$1+9;4*a(1)-3"|tr -dc 0-9|cut -c$1

Được cải thiện bởi Dennis . Cảm ơn!

Các chỉ số là một dựa trên.


11

Python 2, 73 71 73 byte

cảm ơn @aditsu vì đã tăng số điểm của tôi thêm 2 byte

Cuối cùng, một thuật toán có thể hoàn thành dưới 2 giây.

n=10**10010
a=p=2*n
i=1
while a:a=a*i/(2*i+1);p+=a;i+=1
lambda n:`p`[n+1]

Nghĩa là nó!

Sử dụng công thức pi = 4*arctan(1)trong khi tính toán arctan(1)sử dụng loạt taylor của nó.


Khá nhanh. Mặc dù vậy, chỉ mục 1 không có nguồn gốc từ python. Lần cuối cùng tôi nhớ lại (phải thừa nhận rằng tôi đã không hoạt động trong một thời gian), sự đồng thuận là các chức năng cần được xác định, ví dụ f=lambda n:....
primo

2
Hầu như mọi lambda ở đây đều ẩn danh (bạn có thể tìm kiếm câu trả lời bằng Python trong trang web này)
Leaky Nun

Bài viết meta có liên quan . Có vẻ là vi phạm Quy tắc 1 và 3 (sau khi chạy mã của bạn, không có cách nào để nắm bắt những tài liệu tham khảo chức năng; định nghĩa hàm sẽ cần phải được gõ ra cho mỗi đầu vào ( (lambda n:`p`[n+1])(1), (lambda n:`p`[n+1])(2), ...).
primo

1
Bạn không thể chạy mã trực tiếp. Nó giống như việc đặt các importcâu lệnh trước, chỉ là điều này tạo ra một số biến toàn cục trước.
Rò rỉ Nun

i=3 while a:a=i/2*a/i;p+=a;i+=2cho 4.
primo

7

MATL, 11 10 byte

Lưu 1 byte nhờ @Luis

YPiEY$GH+)

Giải pháp này sử dụng lập chỉ mục dựa trên 1

Dùng thử trực tuyến

Tất cả các trường hợp thử nghiệm

Giải trình

YP  % Pre-defined literal for pi
iE  % Grab the input and multiply by 2 (to ensure we have enough digits to work with)
Y$  % Compute the first (iE) digits of pi and return as a string
G   % Grab the input again
H+  % Add 2 (to account for '3.') in the string
)   % And get the digit at that location
    % Implicitly display the result

@LuisMendo Oh yea Tôi đoán đầu ra đã là một chuỗi. Đừng!
Suever

@LuisMendo Oh tôi chưa bao giờ thực sự nghĩ về điều đó. Tôi luôn sử dụng YPtrong thử nghiệm hộp công cụ tượng trưng
Suever

YP có thực sự được cho phép không? Câu hỏi cho biết nó được cho phép nếu nó hỗ trợ <= 10k chữ số
busukxuan

@Suever OP đã nói "tối đa" thay vì "ít nhất". Theo hiểu biết của tôi điều đó có nghĩa là hỗ trợ> 10k bị cấm.
busukxuan

@Suever Vâng, tôi nghĩ rằng tôi có thể, tôi không thể cưỡng lại việc đó lol. Tôi đã xóa câu trả lời Sage của tôi chỉ vì điều đó.
busukxuan

6

Toán học 30 byte

RealDigits[Pi,10,1,-#][[1,1]]&

f=%

f@0
f@1
f@2
f@3
f@10
f@100
f@599
f@760
f@1000
f@10000

1
4
1
5
8
8
2
4
3
5


5

Sage, 32 25 byte

lambda d:`n(pi,9^5)`[d+2]

Câu trả lời đầu tiên của tôi trong một ngôn ngữ của loại này.

nlàm tròn piđến 17775 chữ số.


1
Bạn cần printcuộc gọi, nếu không đây là đoạn mã chỉ hoạt động trong REPL.
Mego

Điều này hoạt động cho (về mặt lý thuyết) bất kỳ đầu vào nào:lambda d:`n(pi,digits=d+5)`[-4]
Mego

2
@Mego không có "99999" chạy?
busukxuan

1
@Mego nhưng sau đó sẽ còn chạy "9" nữa. Tôi không chắc việc nhân đôi chiều dài có thể khiến nó trở nên phổ biến hay không, nhưng tôi nghĩ thậm chí điều đó không thể làm được, do Định lý Khỉ vô hạn: en.wikipedia.org/wiki/Infinite_monkey_theorem
busukxuan

1
@busukxuan Nếu bạn mô hình các chữ số không được tính toán của π là ngẫu nhiên, bạn chắc chắn mong đợi các chuỗi 9 dài tùy ý (và chúng tôi không có lý do gì để mong đợi số thực thực sự khác nhau, mặc dù chúng tôi chưa chứng minh điều này), nhưng bạn chỉ mong đợi một chạy 9 giây miễn là vị trí của nó với xác suất nhỏ đáng kinh ngạc (mặc dù một lần nữa, chúng tôi đã không chứng minh được rằng số π thực sự không hành xử bất ngờ). Chúng tôi đã tìm thấy ít nhất chín số 9, mà tôi nghĩ là đủ để phá vỡ [-8]đề xuất.
Anders Kaseorg


4

Toán học, 23 21 byte

⌊10^# Pi⌋~Mod~10&

SageMath, 24 byte

lambda n:int(10^n*pi)%10

@LLlAMnYP Tôi đã thử điều đó, nhưng Mathicala dường như yêu cầu một khoảng trắng giữa Pi(hoặc giữa #nếu phép nhân được lật), vì vậy việc lưu sẽ biến mất.
Anders Kaseorg

Trên thực tế, nó hoạt động trong Mathicala Online (Tôi đã sử dụng phiên bản console), vì vậy tôi sẽ lấy nó, tôi đoán vậy.
Anders Kaseorg

4
Đây nên là câu trả lời riêng biệt. Mặc dù họ sử dụng cùng một chiến lược, nhưng họ không ở gần cùng một ngôn ngữ.
Mego

@Mego Chính sách tôi tìm thấy không nói câu trả lời bằng các ngôn ngữ khác nhau không thể được tính là rất giống nhau. (Câu trả lời cho thấy không được chấp nhận.) Bạn đang đề cập đến một chính sách khác hay chỉ là một ưu tiên?
Anders Kaseorg

3

J , 19 15 byte

10([|<.@o.@^)>:

Lấy một số nguyên n và xuất ra chữ số thứ n của pi. Sử dụng lập chỉ mục dựa trên không. Để có được chữ số thứ n , hãy tính số pi lần 10 n +1 , lấy số sàn của giá trị đó và sau đó lấy số liệu modulo 10.

Sử dụng

Đầu vào là một số nguyên mở rộng.

   f =: 10([|<.@o.@^)>:
   (,.f"0) x: 0 1 2 3 10 100 599 760 1000
   0 1
   1 4
   2 1
   3 5
  10 8
 100 8
 599 2
 760 4
1000 3
   timex 'r =: f 10000x'
1100.73
   r
5

Trên máy tính của tôi, phải mất khoảng 18 phút để tính toán 10000 thứ chữ số.

Giải trình

10([|<.@o.@^)>:  Input: n
             >:  Increment n
10               The constant n
           ^     Compute 10^(n+1)
        o.@      Multiply by pi
     <.@         Floor it
   [             Get 10
    |            Take the floor modulo 10 and return

3

Clojure, 312 byte

(fn[n](let[b bigdec d #(.divide(b %)%2(+ n 4)BigDecimal/ROUND_HALF_UP)m #(.multiply(b %)%2)a #(.add(b %)%2)s #(.subtract % %2)](-(int(nth(str(reduce(fn[z k](a z(m(d 1(.pow(b 16)k))(s(s(s(d 4(a 1(m 8 k)))(d 2(a 4(m 8 k))))(d 1(a 5(m 8 k))))(d 1(a 6(m 8 k)))))))(bigdec 0)(map bigdec(range(inc n)))))(+ n 2)))48)))48)))

Vì vậy, như bạn có thể nói, tôi không biết tôi đang làm gì. Điều này cuối cùng trở nên hài hước hơn bất cứ điều gì. Tôi đã "pi đến n chữ số" của Google và kết thúc trên trang Wikipedia cho công thức Bailey của BorweinTHER Plouffe . Biết chỉ vừa đủ tính toán (?) Để đọc công thức, tôi đã xoay sở để dịch nó sang Clojure.

Bản dịch không khó lắm. Khó khăn đến từ việc xử lý độ chính xác đến n chữ số, do công thức yêu cầu (Math/pow 16 precision); mà được rất lớn thực sự nhanh chóng. Tôi cần phải sử dụng BigDecimalmọi nơi để làm việc này, điều thực sự làm mọi thứ trở nên khó chịu.

Ung dung:

(defn nth-pi-digit [n]
  ; Create some aliases to make it more compact
  (let [b bigdec
        d #(.divide (b %) %2 (+ n 4) BigDecimal/ROUND_HALF_UP)
        m #(.multiply (b %) %2)
        a #(.add (b %) %2)
        s #(.subtract % %2)]
    (- ; Convert the character representation to a number...
      (int ; by casting it using `int` and subtracting 48
         (nth ; Grab the nth character, which is the answer
           (str ; Convert the BigDecimal to a string
             (reduce ; Sum using a reduction
               (fn [sum k]
                 (a sum ; The rest is just the formula
                       (m
                         (d 1 (.pow (b 16) k))
                         (s
                           (s
                             (s
                               (d 4 (a 1 (m 8 k)))
                               (d 2 (a 4 (m 8 k))))
                             (d 1 (a 5 (m 8 k))))
                           (d 1 (a 6 (m 8 k)))))))
               (bigdec 0)
               (map bigdec (range (inc n))))) ; Create an list of BigDecimals to act as k
           (+ n 2)))
      48)))

Không cần phải nói, tôi chắc chắn có một cách dễ dàng hơn để làm điều này nếu bạn biết bất kỳ môn toán nào.

(for [t [0 1 2 3 10 100 599 760 1000 10000]]
  [t (nth-pi-digit t)])

([0 1] [1 4] [2 1] [3 5] [10 8] [100 8] [599 2] [760 4] [1000 3] [10000 5])

Sau đó tôi nhận ra rằng các toán tử tiêu chuẩn thực sự hoạt động trên các số thập phân lớn, vì vậy các phím tắt ở trên cùng là không cần thiết. Tôi gắn kết sửa lỗi này tại một số điểm. Điều đó có thể sẽ loại bỏ ~ 50 byte.
Carcigenicate

2

Clojure, 253 byte

(defmacro q[& a] `(with-precision ~@a))(defn h[n](nth(str(reduce +(map #(let[p(+(* n 2)1)a(q p(/ 1M(.pow 16M %)))b(q p(/ 4M(+(* 8 %)1)))c(q p(/ 2M(+(* 8 %)4)))d(q p(/ 1M(+(* 8 %)5)))e(q p(/ 1M(+(* 8 %)6)))](* a(-(-(- b c)d)e)))(range(+ n 9)))))(+ n 2)))

Tính số pi bằng công thức này . Phải xác định lại macro with-precisionvì nó được sử dụng quá thường xuyên.

Bạn có thể xem đầu ra ở đây: https://ideone.com/AzumC3 1000 và 10000 mất quá thời gian giới hạn được sử dụng trên ideone, nhún vai


2

Python 3 , 338 byte

Việc thực hiện này dựa trên thuật toán Chudnovsky , một trong những thuật toán nhanh nhất để ước tính pi. Đối với mỗi lần lặp, ước tính khoảng 14 chữ số (hãy xem ở đây để biết thêm chi tiết).

f=lambda n,k=6,m=1,l=13591409,x=1,i=0:not i and(exec('global d;import decimal as d;d.getcontext().prec=%d'%(n+7))or str(426880*d.Decimal(10005).sqrt()/f(n//14+1,k,m,l,x,1))[n+2])or i<n and d.Decimal(((k**3-16*k)*m//i**3)*(l+545140134))/(x*-262537412640768000)+f(n,k+12,(k**3-16*k)*m

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


1

Java 7, 262 260 byte

import java.math.*;int c(int n){BigInteger p,a=p=BigInteger.TEN.pow(10010).multiply(new BigInteger("2"));for(int i=1;a.compareTo(BigInteger.ZERO)>0;p=p.add(a))a=a.multiply(new BigInteger(i+"")).divide(new BigInteger((2*i+++1)+""));return(p+"").charAt(n+1)-48;}

Đã sử dụng thuật toán Python 2 của @ LeakyNun .

Mã thử nghiệm & mã hóa:

Hãy thử nó ở đây.

import java.math.*;
class M{
  static int c(int n){
    BigInteger p, a = p = BigInteger.TEN.pow(10010).multiply(new BigInteger("2"));
    for(int i = 1; a.compareTo(BigInteger.ZERO) > 0; p = p.add(a)){
      a = a.multiply(new BigInteger(i+"")).divide(new BigInteger((2 * i++ + 1)+""));
    }
    return (p+"").charAt(n+1) - 48;
  }

  public static void main(String[] a){
    System.out.print(c(0)+", ");
    System.out.print(c(1)+", ");
    System.out.print(c(2)+", ");
    System.out.print(c(3)+", ");
    System.out.print(c(10)+", ");
    System.out.print(c(100)+", ");
    System.out.print(c(599)+", ");
    System.out.print(c(760)+", ");
    System.out.print(c(1000)+", ");
    System.out.print(c(10000));
  }
}

Đầu ra:

1, 4, 1, 5, 8, 8, 2, 4, 3, 5

1

Smalltalk - 270 byte

Dựa vào danh tính tan⁻¹(x) = x − x³/3 + x⁵/5 − x⁷/7 ..., và đó π = 16⋅tan⁻¹(1/5) − 4⋅tan⁻¹(1/239). SmallTalk sử dụng số học số nguyên chính xác không giới hạn để nó hoạt động cho các đầu vào lớn, nếu bạn sẵn sàng chờ đợi!

|l a b c d e f g h p t|l:=stdin nextLine asInteger+1. a:=1/5. b:=1/239. c:=a. d:=b. e:=a. f:=b. g:=3. h:=-1. l timesRepeat:[c:=c*a*a. d:=d*b*b. e:=h*c/g+e. f:=h*d/g+f. g:=g+2. h:=0-h]. p:=4*e-f*4. l timesRepeat:[t:=p floor. p:=(p-t)*10]. Transcript show:t printString;cr

Lưu dưới dạng pi.stvà chạy như trong các trường hợp thử nghiệm sau. Lập chỉ mục là một dựa trên.

$ gst -q pi.st <<< 1
1
$ gst -q pi.st <<< 2
4
$ gst -q pi.st <<< 3
1
$ gst -q pi.st <<< 4
5
$ gst -q pi.st <<< 11
8
$ gst -q pi.st <<< 101
8
$ gst -q pi.st <<< 600
2
$ gst -q pi.st <<< 761
4
$ gst -q pi.st <<< 1001
3
$ gst -q pi.st <<< 10001 -- wait a long time!
5

1

JavaScript (Node.js) (Chrome 67+), 75 73 67 63 byte

n=>`${eval(`for(a=c=100n**++n*20n,d=1n;a*=d;)c+=a/=d+++d`)}`[n]

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

π/2= =Σk= =0k!/(2k+1)!!

n=>`${eval(`for(a=c=100n**n*20n,d=1n;a*=d;)c+=a/=d+++d`)}`[n]

JavaScript (Node.js) (Chrome 67+), 90 89 byte

n=>`${eval(`for(a=100n**++n*2n,b=a-a/3n,c=0n,d=1n;w=a+b;a/=-4n,b/=-9n,d+=2n)c+=w/d`)}`[n]

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

π/4= =hồ quang(1/2)+hồ quang(1/3)

n=>`${eval(`for(a=100n**n*2n,b=a-a/3n,c=0n,d=1n;w=a+b;a/=-4n,b/=-9n,d+=2n)c+=w/d`)}`[n]

0

Maple, 24 byte

 trunc(10^(n+1)*Pi)mod 10

Các trường hợp thử nghiệm:

> f:=n->trunc(10^(n+1)*Pi)mod 10;
> f(0);
  1
> f(1);
  4
> f(2);
  1
> f(3);
  5
> f(10);
  8
> f(100);
  8
> f(599);
  2
> f(760);
  4
> f(1000);
  3
> f(10000);
  5

0

C #, 252 250 byte

d=>{int l=(d+=2)*10/3+2,j=0,i=0;long[]x=new long[l],r=new long[l];for(;j<l;)x[j++]=20;long c,n,e,p=0;for(;i<d;++i){for(j=0,c=0;j<l;c=x[j++]/e*n){n=l-j-1;e=n*2+1;r[j]=(x[j]+=c)%e;}p=x[--l]/10;r[l]=x[l++]%10;for(j=0;j<l;)x[j]=r[j++]*10;}return p%10+1;}

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

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.