Temukan desimal ke-pi


33

Sudah ada 30 tantangan yang didedikasikan untuk pi tetapi tidak satu pun yang meminta Anda untuk menemukan desimal ke-n, jadi ...

Tantangan

Untuk sembarang bilangan bulat dalam rentang 0 <= n <= 10000tampilan desimal ke-pi.

Aturan

  • Desimal adalah setiap angka setelahnya 3.
  • Program Anda mungkin sebuah fungsi, atau program penuh
  • Anda harus menampilkan hasilnya dalam basis 10
  • Anda dapat memperoleh ndari metode input yang cocok (stdin, input (), parameter fungsi, ...), tetapi tidak hardcoded
  • Anda dapat menggunakan pengindeksan berbasis 1 jika itu asli bahasa pilihan Anda
  • Anda tidak harus berurusan dengan input yang tidak valid ( n == -1, n == 'a'atau n == 1.5)
  • Builtin diizinkan, jika mendukung setidaknya 10 ribu desimal
  • Runtime tidak masalah, karena ini tentang kode terpendek dan bukan kode tercepat
  • Ini adalah , kode terpendek dalam byte yang menang

Uji kasus

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

Untuk referensi, berikut adalah angka 100k pertama pi.


Built-in? misstr(pi())[n+2]
primo

6
Target dupe terdekat IMO adalah Menghitung angka terpotong jumlah kekuatan pi (membebani parameter, atau itu hanya akan menjadi perbedaan terbatas yang diterapkan untuk tantangan ini), Mengirimkan pi secara tepat (menambahkan indeks dan menekan beberapa pencetakan), dan enkripsi jendela Pi .
Peter Taylor

3
@Suever ofcourse! Aturan itu hanya untuk menunjukkan bahwa 10k adalah minimum yang harus bisa ditangani oleh program Anda
Bassdrop Cumberwubwubwub

4
Saya sarankan menambahkan f (599) ke dalam test case, karena dapat dengan mudah membuatnya salah (Anda membutuhkan sekitar 3 desimal presisi ekstra).
aditsu

2
Juga f (760) = 4, yang memulai urutan 4 999999 8, mudah untuk dibulatkan secara keliru.
Anders Kaseorg

Jawaban:


22

05AB1E, 3 byte

žs¤

Dijelaskan

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

Cobalah online

Menggunakan pengindeksan berbasis 1.
Mendukung hingga 100 ribu digit.


Pi ke n digit tidak membulat?
busukxuan

7
@busukxuan No. Ini menggunakan konstanta yang telah ditentukan sebelumnya dari pi hingga 100k digit dan mengambil N dari mereka.
Emigna

4
@ Emigna Itu sangat berguna. Solusi yang bagus
Suever

2
Singkat dan Tajam, PCG dalam kondisi terbaiknya
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]

Input diambil dari stdin.


Contoh Penggunaan

$ 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

Hati-hati menggunakan n dalam algoritma ... output untuk 599 harus 2, bukan 1. Juga Anda mungkin ingin menentukan bahwa Anda menggunakan python 2.
aditsu

@aditsu diperbarui. Dikonfirmasi untuk semua n ≤ 1000 .
Primo

1
Jika Anda ingin nmenjadi input plus 9, Anda dapat menghindari parens.
xnor

@xnor d'oh. Terima kasih;)
primo

2
Beberapa digit pertama yang dihasilkan oleh algoritma ini adalah '3.141596535897932 ...' yang tidak memiliki '2' antara tempat 5 dan 6. Mengapa? Karena saat itulah operator `` Python 2 mulai menambahkan sebuah Lke string.
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

Ditingkatkan oleh Dennis . Terima kasih!

Indeks ini berbasis satu.


11

Python 2, 73 71 73 byte

terima kasih kepada @aditsu untuk meningkatkan skor saya 2 byte

Akhirnya sebuah algoritma yang bisa selesai di bawah 2 detik.

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]

Ide itu!

Menggunakan formula pi = 4*arctan(1)saat menghitung arctan(1)menggunakan seri taylor-nya.


Cukup cepat. Pengindeksan 1 bukan asli ke python. Terakhir saya ingat (memang saya sudah tidak aktif untuk sementara waktu), konsensus adalah bahwa fungsi perlu didefinisikan, misalnya f=lambda n:....
primo

2
Hampir setiap lambda di sini adalah anonim (Anda dapat mencari jawaban dengan Python di situs ini)
Leaky Nun

Pos meta yang relevan . Tampaknya melanggar Aturan 1 dan 3 (setelah menjalankan kode Anda, tidak ada cara untuk menangkap referensi fungsi; definisi fungsi akan perlu mengetik untuk setiap masukan ( (lambda n:`p`[n+1])(1), (lambda n:`p`[n+1])(2), ...).
primo

1
Anda tidak dapat menjalankan kode secara langsung. Ini mirip dengan menempatkan importpernyataan sebelumnya, hanya saja ini membuat beberapa variabel global sebelumnya.
Leaky Nun

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

7

MATL, 11 10 byte

1 byte disimpan berkat @Luis

YPiEY$GH+)

Solusi ini menggunakan pengindeksan berbasis 1

Cobalah secara Online

Semua uji kasus

Penjelasan

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 ya saya kira output sudah menjadi string. Doh!
Suever

@LuisMendo Oh aku tidak pernah memikirkan itu. Saya selalu menggunakan YPpengujian kotak alat simbolis saya
Suever

Apakah YP benar-benar diizinkan? Pertanyaannya mengatakan itu diizinkan jika mendukung <=
10rb

@Suever OP menyatakan "hingga" daripada "setidaknya". Untuk pemahaman saya itu berarti mendukung> 10rb dilarang.
busukxuan

@Suever Ya, saya pikir saya mungkin, saya tidak bisa menahannya untuk melakukannya lol. Saya menghapus jawaban Sage saya hanya karena itu.
busukxuan

6

Mathematica 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]

Jawaban pertama saya dalam bahasa semacam ini.

nputaran pike 17775 digit.


1
Anda perlu printpanggilan, atau ini adalah cuplikan yang hanya berfungsi di REPL.
Mego

Ini berfungsi untuk (secara teoritis) masukan apa pun:lambda d:`n(pi,digits=d+5)`[-4]
Mego

2
@Mego tidak ada "99999" yang berjalan?
busukxuan

1
@Mego tetapi kemudian akan berjalan lebih lama lagi "9". Saya tidak yakin apakah menggandakan panjangnya dapat membuatnya universal, tetapi saya pikir bahkan tidak dapat melakukannya, karena Teorema Monyet Tak Terbatas: en.wikipedia.org/wiki/Infinite_monkey_theorem
busukxuan

1
@busukxuan Jika Anda memodelkan angka omp yang tidak dikomputasi sebagai acak, Anda tentu mengharapkan angka 9s untuk jangka panjang yang sewenang-wenang (dan kami tidak memiliki alasan untuk mengharapkan π yang asli menjadi berbeda, meskipun kami belum membuktikan ini), tetapi Anda hanya mengharapkan run of 9s asalkan posisinya dengan probabilitas yang semakin kecil (meskipun sekali lagi, kami belum membuktikan bahwa π yang sebenarnya tidak berperilaku tidak terduga). Kami telah menemukan setidaknya sembilan angka sembilan, yang menurut saya cukup untuk melanggar [-8]proposal.
Anders Kaseorg


4

Mathematica, 23 21 byte

⌊10^# Pi⌋~Mod~10&

SageMath, 24 byte

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

@ LLLAMnYP Saya mencobanya, tetapi Mathematica tampaknya membutuhkan ruang antara Pidan (atau antara #dan jika perkalian dibalik), sehingga penghematan menghilang.
Anders Kaseorg

Sebenarnya itu berfungsi di Mathematica Online (saya telah menggunakan versi konsol), jadi saya akan menerimanya, saya kira.
Anders Kaseorg

4
Ini harus menjadi jawaban yang terpisah. Meskipun mereka menggunakan strategi yang sama, mereka tidak mendekati bahasa yang sama.
Mego

@Mego Kebijakan yang saya temukan tidak mengatakan jawaban dalam berbagai bahasa tidak dapat dianggap sangat mirip. (Jawaban yang menyarankan itu tidak diterima.) Apakah Anda mengacu pada kebijakan lain atau hanya preferensi?
Anders Kaseorg

3

J , 19 15 byte

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

Mengambil integer n dan menghasilkan digit ke- n dari pi. Menggunakan pengindeksan berbasis nol. Untuk mendapatkan digit ke- n , hitung pi kali 10 n +1 , ambil pijakan nilainya, lalu bawa modulo 10.

Pemakaian

Inputnya adalah integer yang diperluas.

   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

Pada mesin, dibutuhkan sekitar 18 menit untuk menghitung 10000 th digit.

Penjelasan

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

Jadi, seperti yang mungkin Anda tahu, saya tidak tahu apa yang saya lakukan. Ini akhirnya menjadi lebih lucu dari apa pun. Saya Google akan "pi to n digit", dan berakhir di halaman Wikipedia untuk rumus Bailey – Borwein – Plouffe . Mengetahui Kalkulus (?) Yang hanya cukup untuk membaca rumus, saya berhasil menerjemahkannya ke Clojure.

Terjemahan itu sendiri tidak terlalu sulit. Kesulitan datang dari penanganan presisi hingga n-digit, karena formula membutuhkan (Math/pow 16 precision); yang menjadi sangat besar sangat cepat. Saya perlu menggunakan di BigDecimalmana-mana untuk ini untuk bekerja, yang benar-benar membengkak.

Tidak Disatukan:

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

Tak perlu dikatakan, saya yakin ada cara yang lebih mudah untuk melakukan ini jika Anda tahu matematika.

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

Saya kemudian menyadari bahwa operator standar benar-benar bekerja pada desimal besar, sehingga pintasan di atas tidak perlu. Saya me-mount memperbaikinya di beberapa titik. Itu mungkin akan menjatuhkan ~ 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)))

Hitung angka pi menggunakan rumus ini . Harus mendefinisikan ulang makro with-precisionkarena terlalu sering digunakan.

Anda dapat melihat hasilnya di sini: https://ideone.com/AzumC3 1000 dan 10000 melebihi batas waktu yang digunakan pada ideone, mengangkat bahu


2

Python 3 , 338 byte

Implementasi ini didasarkan pada algoritma Chudnovsky , salah satu algoritma tercepat untuk memperkirakan pi. Untuk setiap iterasi, sekitar 14 digit diperkirakan (lihat di sini untuk detail lebih lanjut).

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

Cobalah online!


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

Digunakan @ LeakyNun ini algoritma Python 2 .

Tidak digabungkan & kode uji:

Coba di sini.

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

Keluaran:

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

1

Smalltalk - 270 byte

Bergantung pada identitas tan⁻¹(x) = x − x³/3 + x⁵/5 − x⁷/7 ..., dan itu π = 16⋅tan⁻¹(1/5) − 4⋅tan⁻¹(1/239). SmallTalk menggunakan aritmatika integer presisi tak terbatas sehingga akan bekerja untuk input besar, jika Anda bersedia menunggu!

|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

Simpan sebagai pi.stdan jalankan seperti dalam kasus uji berikut. Pengindeksan adalah berbasis satu.

$ 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]

Cobalah online!

π/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]

Cobalah online!

π/4=arctan(1/2)+arctan(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

Kasus uji:

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

Cobalah online!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.