Hitung pi hingga 5 desimal

15

Ini berasal dari http://programmers.blogoverflow.com/2012/08/20-controversial-programming-opinions/

"Mengingat bahwa Pi dapat diperkirakan menggunakan fungsi 4 * (1 - 1/3 + 1/5 - 1/7 + ...) dengan lebih banyak istilah yang memberikan akurasi lebih besar, tulislah fungsi yang menghitung Pi dengan akurasi 5 tempat desimal. "

  • Catatan, estimasi harus dilakukan dengan menghitung urutan yang diberikan di atas.
tidak
sumber
8
Anda mungkin harus menambahkan beberapa aturan lagi, jika tidak, Anda akan mendapatkan jawaban seperti (python)p=lambda:3.14159
Matt
1
Pernahkah Anda melihat codegolf.stackexchange.com/questions/506/… , yang sangat mirip? Paling tidak, fungsi trigonometri harus dilarang untuk masalah ini karena mereka memungkinkan untuk solusi sepele seperti program
QBASIC ini:?
Saya pikir Anda harus mensyaratkan bahwa algoritma menjadi salah satu pendekatan yang berurutan: semakin lama Anda menghitung, semakin dekat Anda ke pi.
DavidC
@ Davidvider, meskipun secara matematis tak terhindarkan menggunakan seri ini, dari sudut pandang analitik numerik sangat meragukan. Serangkaian bolak-balik konvergen lambat adalah anak poster untuk kehilangan signifikansi.
Peter Taylor
2
Dupe, tetapi sudah sangat tua sehingga tidak ada di sini: stackoverflow.com/q/407518/12274
JB

Jawaban:

10

JavaScript, 46 58 56 45 byte

Pembaruan ES6 : Ternyata ada lebih banyak fitur yang tersedia bagi kami sekarang setelah lima tahun berlalu.

let f=(i=0,a=0)=>i>1e6?a:f(i+4,a+8/-~i/(i+3))

Versi ini ( 45 byte; ya, letdiperlukan) bekerja dalam mode ketat ES6 dalam teori . Dalam praktiknya, Anda dapat menjalankannya di V8 (mis. Dengan simpul) dengan --use-strict --harmony-tailcalls; fitur Proper Tailcalls belum diimplementasikan secara luas, sayangnya. Namun, itu perilaku tertentu, jadi harus baik-baik saja.

Jika kita ingin tetap berpegang pada apa yang diimplementasikan secara luas, dan tidak memerlukan mode ketat, kita cukup menggunakan sintaks panah lemak ES6 untuk fungsi-fungsi tetapi mempertahankan implementasi yang sama seperti sebelumnya (disarankan oleh Brian H) dengan biaya 48 byte.

a=>{for(a=i=0;i<1e6;a+=8/++i/~-(i+=3));return a}

Pilihan nama untuk parameter tunggal tidak terlalu penting, tetapi kami mungkin juga memilih salah satu nama yang kami gunakan untuk meminimalkan polusi ruang lingkup global.


function(){for(a=i=0;i<1e6;a+=8/++i/~-(i+=3));return a}

Versi ini adalah ekspresi fungsi; tambahkan dua karakter (mis. " f") jika Anda menginginkannya namanya. Versi ini mengacaukan global adan i; ini bisa dicegah jika kita menambahkan " a,i" ke daftar parameter.

Manfaatkan versi algoritma yang diformulasi ulang untuk menghindari kebutuhan pengurangan.

 1/1 - 1/3  +   1/5 - 1/7   +    1/9 - 1/11  + ...
(3/3 - 1/3) + (7/35 - 5/35) + (11/99 - 9/99) + ...
    2/3     +      2/35     +       2/99     + ...
  2/(1*3)   +    2/(5*7)    +     2/(9*11)   + ...

Ini versi "biasa" tanpa penyesuaian ini:

function(){for(a=0,i=1;i<1e6;i+=2)a+=[,4,,-4][i%4]/i;return a}

yang memiliki 64 64 karakter.

Terima kasih kepada @ardnew untuk saran untuk menyingkirkan 4*sebelum return.


Sejarah

function(){for(a=i=0;i<1e6;a+=8/++i/~-(i+=3));return a}     // got rid of `i+=4`; restructured
// Old versions below.
function(){for(a=0,i=1;i<1e6;i+=4)a+=8/i/-~-~i;return a}    // got rid of `4*`
function(){for(a=0,i=1;i<1e6;i+=4)a+=2/i/-~-~i;return 4*a}
FireFly
sumber
oO pekerjaan yang sangat bagus, memfaktorkan pengurangan itu.
acolyte
1
kerja bagus, tetapi perlu ditulis sebagai fungsi yang tepat
ardnew
@ardnew: Terima kasih, saya pasti melewatkan detail itu ketika saya membaca deskripsi masalah. Saya telah memperbaruinya, dan sekarang merupakan ekspresi fungsi yang dapat dipanggil (lambda); tidak yakin apakah ini diizinkan atau harus diberi nama. Jika itu masalahnya, itu hanya dua karakter tambahan.
FireFly
1
@FireFly Anda juga dapat mencukur 2 karakter dengan mengubah a+=2/i/-~-~i;return 4*akea+=8/i/-~-~i;return a
ardnew
@ardnew: oh, luar biasa; tidak memikirkan itu. : D
FireFly
8

Python 59 byte

print reduce(lambda x,p:p/2*x/p+2*10**999,range(6637,1,-2))

Ini mencetak 1000 digit; sedikit lebih dari yang dibutuhkan 5. Alih-alih menggunakan iterasi yang ditentukan, ia menggunakan ini:

pi = 2 + 1/3*(2 + 2/5*(2 + 3/7*(2 + 4/9*(2 + 5/11*(2 + ...)))))

Itu 6637 (yang terdalam denominator) dapat dirumuskan sebagai:

digit * 2 * log 2 (10)

Ini menyiratkan konvergensi linier. Setiap iterasi yang lebih dalam akan menghasilkan satu lagi bit biner pi .

Jika , bagaimanapun, Anda bersikeras menggunakan tan -1 identitas, konvergensi yang sama dapat dicapai, jika Anda tidak keberatan akan tentang masalah sedikit berbeda. Melihat jumlah parsial:

4.0, 2.66667, 3.46667, 2.89524, 3.33968, 2.97605, 3.28374, ...

jelas bahwa setiap istilah melompat bolak-balik ke kedua sisi titik konvergensi; seri memiliki konvergensi bolak-balik. Selain itu, setiap istilah lebih dekat ke titik konvergensi daripada istilah sebelumnya; itu benar-benar monoton sehubungan dengan titik konvergensi. Kombinasi kedua sifat ini menyiratkan bahwa rata-rata aritmatika dari dua suku tetangga lebih dekat ke titik konvergensi daripada salah satu dari istilah itu sendiri. Untuk memberi Anda gagasan yang lebih baik tentang apa yang saya maksud, pertimbangkan gambar berikut:

Jumlah Parsial

Seri luar adalah asli, dan seri dalam ditemukan dengan mengambil rata-rata dari masing-masing istilah tetangga. Perbedaan yang luar biasa. Tapi apa yang benar-benar luar biasa, adalah bahwa seri baru ini juga memiliki konvergensi bergantian, dan benar-benar monoton sehubungan dengan titik konvergensi. Itu berarti bahwa proses ini dapat diterapkan berulang kali, ad nauseum.

Baik. Tapi bagaimana caranya?

Beberapa definisi formal. Misalkan P 1 (n) menjadi suku ke- n dari urutan pertama, P 2 (n) menjadi suku ke- n dari urutan kedua, dan demikian pula P k (n) suku ke- n dari urutan ke- k seperti yang didefinisikan di atas .

P 1 = [P 1 (1), P 1 (2), P 1 (3), P 1 (4), P 1 (5), ...]

P 2 = [(P 1 (1) + P 1 (2)) / 2, (P 1 (2) + P 1 (3)) / 2, (P 1 (3) + P 1 (4)) / 2, (P 1 (4) + P 1 (5)) / 2, ...]

P 3 = [(P 1 (1) + 2P 1 (2) + P 1 (3)) / 4, (P 1 (2) + 2P 1 (3) + P 1 (4)) / 4, (P 1 (3) + 2P 1 (4) + P 1 (5)) / 4, ...]

P 4 = [(P 1 (1) + 3P 1 (2) + 3P 1 (3) + P 1 (4)) / 8, (P 1 (2) + 3P 1 (3) + 3P 1 (4) + P 1 (5)) / 8, ...]

Tidak mengherankan, koefisien ini mengikuti persis koefisien binomial, dan dapat dinyatakan sebagai satu baris tunggal Segitiga Pascal. Sejak baris sewenang-wenang Segitiga Pascal adalah sepele untuk menghitung, sebuah sewenang-wenang 'dalam' seri dapat ditemukan, hanya dengan mengambil pertama n parsial jumlah, kalikan masing-masing dengan istilah yang sesuai dalam k th deretan Segitiga Pascal, dan membaginya dengan 2 k-1 .

Dengan cara ini, presisi titik mengambang 32-bit penuh (~ 14 tempat desimal) dapat dicapai hanya dengan 36 iterasi, di mana titik jumlah parsial bahkan belum bertemu di tempat desimal kedua. Ini jelas bukan golf:

# used for pascal's triangle
t = 36; v = 1.0/(1<<t-1); e = 1
# used for the partial sums of pi
p = 4; d = 3; s = -4.0

x = 0
while t:
  t -= 1
  p += s/d; d += 2; s *= -1
  x += p*v
  v = v*t/e; e += 1

print "%.14f"%x

Jika Anda menginginkan presisi yang sewenang-wenang, ini dapat dicapai dengan sedikit modifikasi. Di sini sekali lagi menghitung 1000 digit:

# used for pascal's triangle
f = t = 3318; v = 1; e = 1
# used for the partial sums of pi
p = 4096*10**999; d = 3; s = -p

x = 0
while t:
  t -= 1
  p += s/d; d += 2; s *= -1
  x += p*v
  v = v*t/e; e += 1

print x>>f+9

Nilai awal p mulai 2 10 lebih besar, untuk menetralkan efek pembagian bilangan bulat dari s / d ketika d menjadi lebih besar, menyebabkan beberapa digit terakhir tidak bertemu. Perhatikan di sini lagi itu3318 itu juga:

digit * log 2 (10)

Jumlah iterasi yang sama dengan algoritma pertama (dibelah dua karena t berkurang 1 bukannya 2 setiap iterasi). Sekali lagi, ini menunjukkan konvergensi linier: satu bit biner pi per iterasi. Dalam kedua kasus, 3318 iterasi diperlukan untuk menghitung 1000 digit pi , sebagai kuota sedikit lebih baik dari 1 juta iterasi untuk menghitung 5.

primo
sumber
Itu jauh lebih baik daripada solusi saya:4 * sum(1/(1+i*2) if not i%2 else -1/(1+i*2) for i in xrange(places*10**(places)))
Aaron Hall
1
Ini sangat mirip dengan pendekatan saya , yang kebetulan merupakan bentuk berbeda dari Anda. Di tambang, saat k → ∞, f(-1,k)mendekati Euler-sum Anda.
Simply Beautiful Art
1
Sangat keren; analisis dan penjelasan yang luar biasa, terima kasih.
jeremy radcliff
Hanya hal kecil. Bukankah maksud Anda setelah P_1 = ..., P_2 = ..., P_3 = ..., P_4 = ..., "... kalikan masing-masing dengan istilah yang sesuai di kthbaris Segitiga Pascal, dan bagi dengan 2^{k-1}.", Bukan nthbaris dan 2^{n-1}?
jeremy radcliff
@ Jeremyradcliff saya lakukan, ya. Terima kasih atas koreksinya.
Primo
5

Mathematica 42 39 34 33 31 26 32

Pendekatan Archimedes 26 karakter

N@#*Sin[180 Degree/#]&

Ini mencapai kriteria ketika input 822.

Pertanyaan: Adakah yang tahu bagaimana dia menghitung Dosa 180 derajat? Bukan saya.


Pendekatan Leibniz (seri Gregory) 32 karakter

Ini adalah fungsi yang sama dengan problem poser sebagai contoh. Itu mencapai kriteria di sekitar setengah juta iterasi.

N@4Sum[(-1)^k/(2k+1),{k,0,10^6}]

Pendekatan Madhava-Leibniz 37 karakter

Variasi ini menggunakan beberapa karakter lagi tetapi konvergen ke kriteria hanya dalam 9 iterasi!

N@Sqrt@12 Sum[(-1/3)^k/(2k+1),{k,0,9}]
DavidC
sumber
semua itu menghitungnya dengan algoritma yang diberikan dalam definisi masalah?
acolyte
Pendekatan @acolyte Leibniz '(sekarang yang pertama terdaftar) memang yang disebutkan dalam deskripsi masalah. Sangat lambat untuk bertemu. Sedikit variasi di atasnya (Madhava-Leibniz) menyatu dengan sangat cepat.
DavidC
Dosa 180 ° cukup mudah. Ini 180 ° / N yang bisa menjadi rumit di luar dari tersangka yang biasa untuk N.
JB
Tolong jelaskan, @JB Tricky to ukur?
DavidC
Entri ini harus menyatakan "32" karena hanya pendekatan Leibniz yang memenuhi persyaratan (menghitung karakter dalam kode seperti yang diberikan, saya mendapatkan 34, tetapi kedua spasi dapat dihilangkan dengan aman, memberikan memang panjangnya 32).
celtschk
4

APL (14)

4×-/÷1-⍨2×⍳1e6

 

marinus
sumber
1
13,--/4÷1-2×⍳1e6
Timtech
4

Jawa (67 karakter)

float r(){float p=0,s=4,i=1E6f;while(--i>0)p+=(s=-s)/i--;return p;}

Perhatikan bahwa ini menghindari hilangnya makna dengan menambahkan angka-angka dalam urutan yang benar.

Peter Taylor
sumber
ini juga sepenuhnya sesuai dengan kode C. jika diposting sebagai C, Anda bisa mengubah while(--i>0)ke while(i--)dan menyimpan 2 chars
ardnew
1
@ardnew, benar, tetapi dengan C ada banyak trik yang lebih menarik untuk dimainkan ...
Peter Taylor
4

Haskell, 32

foldr(\k->(4/(2*k+1)-))0[0..8^7]

GHCi> foldr (\ k -> (4 / (2 * k + 1) -)) 0 [0..8 ^ 7]
3.141593130426724

Menghitung nama fungsi itu

34

π=foldr(\k->(4/(2*k+1)-))0[0..8^7]
tidak lagi mengaktifkan counterclockwis
sumber
3

R - 25 karakter

sum(c(4,-4)/seq(1,1e6,2))
flodel
sumber
3

C (GCC) (44 karakter)

float p(i){return i<1E6?4./++i-p(++i):0;}

Itu 41 karakter, tetapi juga harus dikompilasi -O2untuk mendapatkan optimiser untuk menghilangkan rekursi ekor. Ini juga bergantung pada perilaku yang tidak terdefinisi sehubungan dengan urutan ++eksekusi; terima kasih kepada ugoren karena menunjukkan ini. Saya sudah menguji dengan gcc 4.4.3 di Linux 64-bit.

Perhatikan bahwa kecuali pengoptimal juga menata ulang jumlah, itu akan menambah dari jumlah terkecil, sehingga itu menghindari hilangnya signifikansi.

Sebut sebagai p().

Peter Taylor
sumber
Panggilan rekursif Anda q()bukan p(). Dan saya tidak berpikir -O2harus dihitung (tetapi jika Anda menghitungnya, itu 4 karakter karena ruang yang diperlukan).
ugoren
Juga: 1. gcc 4.1.1 tidak mengoptimalkan rekursi (dan saya tidak mengerti bagaimana bisa), sehingga stack meluap. 2. itu harus disebut sebagai p(0). 3. Simpan char dengan return++i.... 4. Dua ++imembuat perilaku yang tidak terdefinisi.
ugoren
@ugoren, terima kasih atas komentar Anda. Agar: q- itu akan mengajarkan saya untuk memeriksa ulang setelah mengganti nama. Saya pikir saya mengikuti praktik normal dalam menghitung -O2sebagai 3 karakter, tetapi kita bisa membukanya dengan meta jika Anda mau; meta.codegolf.stackexchange.com/questions/19 adalah satu-satunya diskusi yang relevan yang dapat saya temukan. Saya telah menambahkan versi gcc yang saya gunakan, dan yang memungkinkan saya menyebutnya sebagai p(). Menyimpan char menghentikan optimizer dan memberikan segfault. Saya akan mengklarifikasi bahwa saya menggunakan perilaku yang tidak terdefinisi, sesuai meta.codegolf.stackexchange.com/questions/21
Peter Taylor
Saya menambahkan jawaban untuk pertanyaan meta tentang bendera. Tentang p()- apakah Anda yakin menelepon p()dari konteks apa pun akan berhasil? Atau hanya apa yang terjadi pada tumpukan dalam tes Anda?
ugoren
@ugoren, mungkin saya beruntung secara konsisten. Bahkan jika saya menyebutnya dua kali berturut-turut, yang kedua masih mengembalikan nilai yang benar. gcc tampaknya menghasilkan kode yang sedikit berbeda untuk p()vs p(0), tapi saya tidak tahu perilaku apa yang didokumentasikan dan saya tidak benar-benar seorang programmer C.
Peter Taylor,
3

J, 26 karakter

+ / + / _ 2 ((4 _4) &%)>: +: i.100

Pindah dari 100 item urutan ke 1e6 item. Juga sekarang ini adalah kode yang ditandai dan dapat disalin dari peramban ke konsol tanpa kesalahan.

+/+/_2((4 _4)&%)\>:+:i.1e6
fftw
sumber
3
-/4%>:2*i.1e6- 13 karakter. (Terima kasih kepada b_jonas di #jsoftware untuk membuat saya menyadari bahwa -/berfungsi menghitung jumlah dengan tanda bolak-balik. [Ini karena semua operator di J memiliki prioritas dan asosiasi yang tepat, jadi -/ 1 2 3 4<=> 1 - (2 - (3 - 4))<=> 1 - 2 + 3 - 4.])
FireFly
itu rapi dan dua kali lebih luar biasa. Atau bahkan 2 ^ 10 lebih keren!
fftw
@FireFly itu indah
Jonah
2

Javascript - 33 Karakter

p=x=>4*(1-(x&2))/x+(x>1?p(x-2):0)

Panggilan pmelewati nomor ganjil positif xdan itu akan menghitung Pi dengan (x-1)/2syarat.

MT0
sumber
2

Ruby - 82 karakter

def f(n,k=n)k>0?(f(n,k-1)+f(n+1,k-1))/2:n<0?0:f(n-1,0)+(-1)**n/(2*n+1.0)end;4*f(9)

Cobalah: https://repl.it/LQ8w

Pendekatan ini menggunakan seri yang diberikan secara tidak langsung menggunakan pendekatan akselerasi numerik. Output yang dihasilkan adalah

pi ≈ 3.14159265161

vs.

pi = 3.14159265359

Dimulai dengan

f(n,0) = 1/1 - 1/3 + 1/5 - ... + ((-1)**n)/(2*n+1)

Dan kemudian, karena ini bergantian, kita dapat mempercepat konvergensi menggunakan

f(n,1) = (f(n,0) + f(n+1,0))/2

Dan itu berulang kali menerapkan ini:

f(n,k) = (f(n,k-1) + f(n+1,k-1))/2

Dan untuk kesederhanaan f(n) = f(n,n),.


Ruby - 50 karakter

Jika Anda tidak keberatan berlari untuk waktu yang sangat lama, maka Anda bisa menggunakannya

def f(n)n<0?0:f(n-1)+(-1)**n/(2*n+1.0)end;4*f(1e7)

atau

a=0;for k in 0..1e7 do a+=(-1)**k/(2*k+1.0)end;4*a
Seni Cukup Indah
sumber
1

C, 69 karakter

float p,b;void main(a){b++<9e6?p+=a/b++,main(-a):printf("%f\n",4*p);}
  • Jalankan tanpa parameter baris perintah (jadi adiinisialisasi ke 1).
  • Harus dikompilasi dengan optimasi.
  • void mainaneh dan tidak standar, tetapi membuat hal-hal berfungsi. Tanpa itu, rekursi diimplementasikan sebagai panggilan nyata, yang mengarah ke stack overflow. Alternatif menambahkan return.
  • Dua karakter 4*dapat disimpan, jika dijalankan dengan tiga parameter baris perintah.
ugoren
sumber
Anda dapat mempersingkat itu int main(a)atau bahkan main(a), GCC hanya memberikan peringatan. Dan itu akan memberikan peringatan void main, dan mungkin bahkan karena Anda hanya memiliki satu argumen main.
nyuszika7h
1

Clojure - 79 karakter

(fn [](* 4(apply +(map #(*(Math/pow -1 %1)(/ 1.0(+ 1 %1 %1)))(range 377000)))))

Ini menciptakan fungsi tanpa argumen yang akan menghitung float yang mendekati pi dengan benar ke lima tempat desimal. Perhatikan bahwa ini tidak mengikat fungsi untuk nama seperti pi, sehingga kode ini harus baik dievaluasi di tempat dengan evalsebagai (<code>)atau terikat dengan nama dalam hal solusinya adalah

(defn p[](* 4(apply +(map #(*(Math/pow -1 %1)(/ 1.0(+ 1 %1 %1)))(range 377000)))))

untuk 82 karakter

Tentang

(defn nth-term-of-pi [n] (* (Math/pow -1 n) (/ 1.0 (+ 1 n n))))
(defn pi [c] (* 4 (apply + (map nth-term-of-pi (range c)))))
(def  pi-accuracy-constant (loop [c 1000] (if (< (pi c) 3.14159) (recur (inc c)) c)))
; (pi pi-accuracy-constant) is then the value of pi to the accuracy of five decimal places
arrdem
sumber
1

PHP - 56 55 karakter

<?for($j=$i=-1;1e6>$j;){$p+=($i=-$i)/($j+=2);}echo$p*4;

Saya tidak tahu bahwa saya bisa mendapatkannya lebih kecil tanpa melanggar aturan algoritma.

TwoScoopsofPig
sumber
1
Bagaimana dengan ini untuk 45? <?for(;1e6>$j;)$p+=($i=-$i|4)/~-$j+=2;echo$p;
primo
Saya mencoba untuk datang dengan itu, tetapi tidak bisa mendapatkan operasi bitwise untuk bekerja. Terima kasih untuk sarannya!
TwoScoopsofPig
Anda dapat menghapus titik koma terakhir untuk menyimpan 1 karakter.
nyuszika7h
1

Perl - 43 39 karakter

tidak yakin aturan tentang subrutin anonim, tapi inilah implementasi lain menggunakan konstruksi seri @ FireFly

sub{$s+=8/((4*$_+2)**2-1)for 0..1e6;$s}

sub p{$s+=(-1)**$_*4/(2*$_+1)for 0..1e6;$s}

ardnew
sumber
0

Java - 92 84 karakter

Sejauh ini saya tidak bisa mengalahkan hasil Peter Taylor, tetapi inilah milik saya:

double d(){float n=0,k=0,x;while(n<9E5){x=1/(1+2*n++);k+=(n%2==0)?-x:x;}return 4*k;}

Versi tidak disatukan:

double d() {
    float n = 0, k = 0, x;
    while (n < 9E5) {
        x = 1 / (1 + 2 * n++);
        k += (n % 2 == 0) ? -x : x;
    }
    return 4 * k;
}

Sunting: Menyimpan beberapa karakter menggunakan operator ternary.

Averroes
sumber
0

Python - 56 karakter

Meh, Python-fu saya tidak cukup kuat. Saya tidak bisa melihat jalan pintas lagi, tapi mungkin pegolf yang lebih berpengalaman bisa menemukan sesuatu untuk di-trim di sini?

t=s=0
k=i=1
while t<1e6:t,s,i,k=t+1,k*4./i+s,i+2,-k
chucksmash
sumber
Anda bisa menggunakan Python 3 untuk menyimpan satu byte untuk divisi float ( 4.-> 4). Dalam berita lain, saya baru saja menemukan sebuah kasus di mana Python 3 sebenarnya mengalahkan Python 2 dalam kode golf!
nyuszika7h
0

Ruby - 54 karakter

def a()p=0;1000000.times{|i|p+=8/(4*i*(4*i+2))};p;end;

Coba pertama saya di konsol

def a()i=1;p=0;while i<2**100 do p+=8/(i*(i+2));i+=4;end;p;end;

63 karakter.

Perello
sumber
Anda dapat menyimpan byte dengan menggunakan def a;alih-alih def a().
nyuszika7h
Satu lagi dengan menghapus titik koma terakhir.
nyuszika7h
0

Perl (76 karakter)

$y=1e4;for$x(0..1e4-1){$y--while sqrt($x**2+$y**2)>1e4;$a+=$y}print 4*$a/1e8

(Hasil: 3.14159052)

Bukan solusi sesingkat mungkin, tetapi mungkin menarik. Itu yang geometris. Saya menghitung area di bawah lingkaran.

Saya mendapat pendekatan lucu lain, tetapi sangat lambat. Ini menghitung jumlah titik diskrit dalam kotak yang berada di bawah seperempat lingkaran dan menghitung pi darinya:

$i=shift;for$x(0..$i){for$y(0..$i){$h++if sqrt($x**2+$y**2)<$i}}print$h*4/$i**2

Itu mengharapkan jumlah iterasi sebagai argumen baris perintah. Di sini Anda dapat melihat bagaimana run time terkait dengan akurasi. ;)

$ time perl -e '$i=shift;for$x(0..$i){for$y(0..$i){$h++if sqrt($x**2+$y**2)<$i}}print$h*4/$i**2' 100
3.1796
real    0m0.011s
user    0m0.005s
sys 0m0.003s

$ time perl -e '$i=shift;for$x(0..$i){for$y(0..$i){$h++if sqrt($x**2+$y**2)<$i}}print$h*4/$i**2' 1000
3.14552
real    0m0.354s
user    0m0.340s
sys 0m0.004s

$ time perl -e '$i=shift;for$x(0..$i){for$y(0..$i){$h++if sqrt($x**2+$y**2)<$i}}print$h*4/$i**2' 10000
3.14199016
real    0m34.941s
user    0m33.757s
sys 0m0.097s
memowe
sumber
0

k (25 karakter)

4 * + /% (i # 1 -1) '1 + 2 ! I: 1000000

Sedikit lebih pendek:

+/(i#4 -4)%1+2*!i:1000000
skeevey
sumber
0

Python (49)

print 4*sum((-1)**i/(2*i+1.)for i in range(9**6))
3.14159 453527
arshajii
sumber
0

CJam - 21

1e6{WI#4d*I2*)/}fI]:+

Perhitungan yang cukup mudah dari seri yang diberikan.
CJam adalah http://sf.net/p/cjam

aditsu
sumber
0

Julia - 30 karakter

sum(4./[1:4:1e6] - 4./[3:4:1e6])
Milktrader
sumber
0

SQL, 253 byte

DECLARE @B int=3, @A varchar(max), @C varchar(max)='1'
WHILE @B<100000
BEGIN
SELECT @C=@C+(select case when (@B-1)%4=0 then'+'else'-'end)+
(SELECT cast(cast(1.0/@B as decimal(9,8)) as varchar(max)))
SELECT @B=@B+2
END
EXECUTE('SELECT 4*('+@C+')')

Saya akan memberikan SQL Fiddle, tetapi ini terlalu banyak loop menemukan fraksi 1/3 1/5 1/7 dll dan memberikan kesalahan lol. Namun, jika Anda mengubah @B<100000untuk 1000kemudian berjalan (jelas tidak dengan jumlah yang sama digit akurasi).

phroureo
sumber
0

Befunge, 129 byte

p08p109p^v*86%+55:<$$$<
\$\>:#,_@>+\55+/:#^_"."
v>p"~"/:"~"%08p"~"/00p:2\4%-*"(}"
8^90%"~":+2:+g90*+g80*<
>*:**\/+>"~~"00g:"~"`!|

Cobalah online!

Jika ada yang bertanya-tanya, itu adalah gajah.

Gajah kartun

James Holderness
sumber