คำนวณ pi ถึง 5 ทศนิยม


15

สิ่งนี้มาจากhttp://programmers.blogoverflow.com/2012/08/20-controversial-programming-opinions/

"เนื่องจาก Pi สามารถประมาณได้โดยใช้ฟังก์ชั่น 4 * (1 - 1/3 + 1/5 - 1/7 + …) พร้อมเงื่อนไขเพิ่มเติมที่ให้ความแม่นยำมากขึ้นเขียนฟังก์ชันที่คำนวณ Pi ถึงความแม่นยำทศนิยม 5 ตำแหน่ง "

  • หมายเหตุการประเมินจะต้องทำโดยการคำนวณลำดับที่ได้รับข้างต้น

8
คุณควรเพิ่มกฎเพิ่มเติมอีกไม่งั้นคุณจะได้คำตอบเช่น (python)p=lambda:3.14159
Matt

1
คุณเคยเห็นcodegolf.stackexchange.com/questions/506/…ซึ่งคล้ายกันมาก? อย่างน้อยที่สุดฟังก์ชั่นตรีโกณมิติควรถูกห้ามเพราะปัญหาเหล่านี้ทำให้เกิดการแก้ปัญหาเล็กน้อยเช่นโปรแกรม QBASIC นี้: INT (4E5 * ATN (1)) / 1E5
กรุณารอ

ฉันคิดว่าคุณควรกำหนดให้อัลกอริทึมเป็นหนึ่งในการประมาณต่อเนื่อง: ยิ่งคุณคำนวณได้นานเท่าไหร่คุณยิ่งใกล้ถึงปี่
DavidC

@DavidCarraher ถึงแม้ว่ามันจะหลีกเลี่ยงไม่ได้ในทางคณิตศาสตร์ในการใช้ซีรี่ส์นี้จากมุมมองเชิงวิเคราะห์เชิงตัวเลขมันน่าสงสัยอย่างมาก บรรจบกันอย่างช้า ๆ สลับกันเป็นโปสเตอร์เด็กสูญเสียความสำคัญ
Peter Taylor

2
Dupe แต่มันเก่ามากมันไม่ได้อยู่ที่นี่: stackoverflow.com/q/407518/12274
JB

คำตอบ:


10

JavaScript, 46 58 56 45 ไบต์

อัปเดต ES6 : ปรากฎว่ามีคุณสมบัติอื่น ๆ อีกมากมายสำหรับเราที่ผ่านมาห้าปี

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

รุ่นนี้ ( 45ไบต์; ใช่letเป็นสิ่งจำเป็น) ทำงานในโหมดเข้มงวด ES6 ในทฤษฎี ในทางปฏิบัติคุณสามารถรันใน V8 (เช่นกับโหนด) ด้วย--use-strict --harmony-tailcalls; คุณลักษณะ Tailcalls ที่เหมาะสมยังไม่ได้ใช้อย่างกว้างขวาง อย่างไรก็ตามมันเป็นพฤติกรรมที่ระบุดังนั้นควรปรับ

ถ้าเราต้องการที่จะยึดติดกับสิ่งที่นำมาใช้กันอย่างแพร่หลายและไม่จำเป็นต้องเข้มงวดโหมดเราก็สามารถใช้ ES6 ไวยากรณ์ไขมันลูกศรสำหรับฟังก์ชั่น แต่อย่างอื่นยังคงมีการดำเนินการเช่นเดียวกับก่อน (แนะนำโดยไบรอัน H) สำหรับค่าใช้จ่ายของ48ไบต์

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

ทางเลือกของชื่อสำหรับพารามิเตอร์เดียวไม่ได้จริงๆว่า แต่เราอาจรวมทั้งเลือกหนึ่งในรายชื่อที่เราใช้เพื่อลดมลพิษทั่วโลกขอบเขต


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

รุ่นนี้เป็นฟังก์ชั่นการแสดงออก; เพิ่มอักขระสองตัว (เช่น " f") หากคุณต้องการตั้งชื่อ รุ่นนี้ปิดบัง globals aและi; สิ่งนี้สามารถป้องกันได้หากเราเพิ่ม "a,i " ลงในรายการพารามิเตอร์

ทำให้การใช้อัลกอริทึมรุ่น reformulated เพื่อหลีกเลี่ยงความต้องการในการลบ

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

นี่คือรุ่น "ธรรมดา" ที่ไม่มีการปรับค่านี้:

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

ซึ่งนาฬิกาในที่64 62ตัวอักษร

ขอบคุณ @ardnew สำหรับข้อเสนอแนะที่จะกำจัด4*ก่อนreturnก่อน


ประวัติศาสตร์

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}

o เป็นงานที่ดีมากโดยแยกการลบออก
acolyte

1
ทำงานได้ดี แต่ต้องเขียนเป็นฟังก์ชั่นที่เหมาะสม
ardnew

@ardnew: ขอบคุณฉันต้องพลาดรายละเอียดนั้นเมื่อฉันอ่านคำอธิบายปัญหา ฉันได้อัปเดตแล้วและตอนนี้ก็เป็นฟังก์ชั่นการโทรได้ (แลมบ์ดา); ไม่แน่ใจว่าสิ่งนี้ได้รับอนุญาตหรือต้องให้ชื่อ ถ้าเป็นเช่นนั้นมันก็เป็นแค่ตัวละครอีกสองตัวอยู่ดี
FireFly

1
@FireFly คุณยังสามารถโกน 2 ตัวอักษรโดยเปลี่ยนa+=2/i/-~-~i;return 4*aเป็นa+=8/i/-~-~i;return a
ardnew

@ardnew: โอ้ยอดเยี่ยม; ไม่ได้คิดอย่างนั้น : D
FireFly

8

Python 59 ไบต์

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

พิมพ์ออก 1,000 หลัก มากกว่าเล็กน้อยที่ต้องการเล็กน้อย 5. แทนที่จะใช้การวนซ้ำตามที่กำหนดมันใช้สิ่งนี้:

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

6637(ตัวหารสุด) สามารถสูตร:

ตัวเลข * 2 * บันทึก2 (10)

สิ่งนี้แสดงถึงการลู่เชิงเส้น แต่ละซ้ำลึกจะผลิตหนึ่งบิตไบนารีมากขึ้นของปี่

อย่างไรก็ตามหากคุณยืนยันในการใช้เอกลักษณ์ tan -1การลู่เข้าที่คล้ายกันสามารถทำได้ถ้าคุณไม่สนใจปัญหาจะแตกต่างกันเล็กน้อย ดูที่ผลรวมบางส่วน:

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

เห็นได้ชัดว่าแต่ละเทอมกระโดดข้ามไปมาทั้งสองข้างของจุดบรรจบกัน ชุดนี้มีการบรรจบกัน นอกจากนี้แต่ละคำศัพท์จะอยู่ใกล้กับจุดบรรจบมากกว่าคำก่อนหน้าคือ มันเป็นเสียงเดียวอย่างแน่นอนด้วยความเคารพต่อจุดบรรจบของมัน การรวมกันของคุณสมบัติทั้งสองนี้แสดงว่าค่าเฉลี่ยเลขคณิตของคำศัพท์สองคำที่อยู่ใกล้กันนั้นอยู่ใกล้กับจุดบรรจบกันมากกว่าคำศัพท์ใดคำหนึ่ง เพื่อให้คุณมีความคิดที่ดีขึ้นเกี่ยวกับสิ่งที่ฉันหมายถึงพิจารณาภาพต่อไปนี้:

Partial Sums

ซีรี่ส์ด้านนอกเป็นต้นฉบับและซีรีย์ด้านในพบได้โดยการหาค่าเฉลี่ยของแต่ละคำที่อยู่ใกล้เคียง ความแตกต่างที่น่าทึ่ง แต่สิ่งที่โดดเด่นอย่างแท้จริงคือซีรีย์ใหม่นี้ยังมีคอนเวอร์เจนซ์แบบสลับและเป็นแบบโมโนโทนิกที่เกี่ยวกับจุดบรรจบของมัน ซึ่งหมายความว่ากระบวนการนี้สามารถนำมาใช้ซ้ำแล้วซ้ำอีกโฆษณาคลื่นไส้

ตกลง. แต่อย่างไร

คำจำกัดความบางอย่างเป็นทางการ Let P 1 (n)เป็นn THระยะของลำดับแรกP 2 (n)เป็นn THระยะของลำดับที่สองและในทำนองเดียวกันP k (n) n THระยะเวลาของk THลำดับตามที่ระบุไว้ข้างต้น .

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, ... ]

ไม่น่าแปลกใจที่ค่าสัมประสิทธิ์เหล่านี้เป็นไปตามสัมประสิทธิ์ทวินามและสามารถแสดงเป็นแถวเดียวของสามเหลี่ยมปาสคาล เนื่องจากแถวใด ๆ ของสามเหลี่ยมปาสคาลนั้นมีความสำคัญในการคำนวณจึงสามารถหาอนุกรม 'ลึก' แบบสุ่มได้โดยการหาผลรวมnส่วนแรกคูณด้วยแต่ละคำที่สอดคล้องกันในแถวลำดับที่ kของสามเหลี่ยมปาสกาลและหารด้วย2 K-1

ด้วยวิธีนี้ความแม่นยำของจุดลอยตัวแบบ 32 บิตเต็มรูปแบบ (ทศนิยม 14 ตำแหน่ง) สามารถทำได้เพียง 36 รอบโดยที่ผลรวมบางส่วนยังไม่ได้รวมอยู่ในตำแหน่งทศนิยมที่สอง เห็นได้ชัดว่านี่ไม่ใช่การเล่นกอล์ฟ:

# 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

หากคุณต้องการความแม่นยำโดยพลการสิ่งนี้สามารถทำได้ด้วยการดัดแปลงเล็กน้อย ที่นี่อีกครั้งคำนวณ 1,000 หลัก:

# 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

ค่าเริ่มต้นของpเริ่มใหญ่ขึ้น2 10เพื่อต่อสู้กับผลกระทบของการหารจำนวนเต็มของs / dเมื่อdกลายเป็นใหญ่ขึ้นทำให้ตัวเลขสองสามหลักสุดท้ายไม่มาบรรจบกัน แจ้งให้ทราบที่นี่อีกครั้งว่า3318 :

ตัวเลข * บันทึก2 (10)

จำนวนการทำซ้ำเดียวกันกับอัลกอริทึมแรก (ลดลงครึ่งหนึ่งเนื่องจากtลดลง1แทนที่จะเป็น2ซ้ำในแต่ละครั้ง) สิ่งนี้บ่งบอกถึงการลู่เข้าเชิงเส้น: ไบนารี่บิตหนึ่งของpiต่อการวนซ้ำ ในทั้งสองกรณีต้องใช้การคำนวณซ้ำ 3318 ครั้งเพื่อคำนวณ 1,000 หลักของpiซึ่งเป็นโควต้าที่ดีกว่า 1 ล้านซ้ำในการคำนวณ 5


ดีกว่าวิธีแก้ปัญหาของฉัน: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
นี่คล้ายกับแนวทางของฉันซึ่งเป็นรูปแบบที่แตกต่างจากคุณ ในเหมืองเป็นk → ∞, f(-1,k)วิธีการออยเลอร์ผลรวมของคุณ
ศิลปะที่สวยงามเรียบง่าย

1
เจ๋งมาก; การวิเคราะห์และคำอธิบายที่ยอดเยี่ยมขอบคุณ
jeremy radcliff

เป็นเพียงเรื่องเล็ก ๆ คุณไม่ได้หมายถึงหลังจากP_1 = ..., P_2 = ..., P_3 = ..., P_4 = ..."... คูณแต่ละคำด้วยคำที่เกี่ยวข้องในkthแถวของสามเหลี่ยมปาสคาลและหารด้วย2^{k-1}" แทนที่จะเป็นnthแถวและ2^{n-1}?
jeremy radcliff

@ jeremyradcliff ฉันทำแล้วใช่ ขอบคุณสำหรับการแก้ไข
primo

5

Mathematica 42 39 34 33 31 26 32

วิธีการของอาร์คิมีดีส 26 ตัว

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

สิ่งนี้ถึงเกณฑ์เมื่ออินพุตคือ 822

คำถาม: ไม่มีใครรู้ว่าเขาคำนวณบาป 180 องศาได้อย่างไร ฉันไม่.


แนวทางของ Leibniz (ชุดของ Gregory) 32 ตัวอักษร

นี่เป็นฟังก์ชั่นเดียวกับที่ปัญหาที่ตอบยากให้เป็นตัวอย่าง ถึงเกณฑ์ในรอบครึ่งล้านซ้ำแล้วซ้ำอีก

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

Madhava-Leibniz เข้าใกล้ 37 ตัวอักษร

ชุดรูปแบบนี้ใช้อักขระเพิ่มอีกไม่กี่ตัว แต่มาบรรจบกันเป็นเกณฑ์ในการทำซ้ำ 9 ครั้งเท่านั้น!

N@Sqrt@12 Sum[(-1/3)^k/(2k+1),{k,0,9}]

ทั้งหมดนั้นคำนวณโดยอัลกอริทึมที่ให้ไว้ในคำจำกัดความปัญหาหรือไม่
acolyte

@acolyte Leibniz 'วิธีการ (ตอนนี้คนแรกที่ระบุไว้) แน่นอนหนึ่งที่กล่าวถึงในคำอธิบายของปัญหา มันช้ามากที่จะมาบรรจบกัน ความแตกต่างเล็กน้อยกับมัน (Madhava-Leibniz) มาบรรจบกันอย่างรวดเร็ว
DavidC

ไซน์ของ 180 °ค่อนข้างง่าย มันคือ 180 ° / N ที่สามารถหลบหนีจากผู้ต้องสงสัยตามปกติสำหรับ N.
JB

กรุณาอธิบาย @JB หากินเพื่อวัด?
DavidC

รายการนี้ควรระบุ "32" เนื่องจากวิธีการของ Leibniz เท่านั้นที่เป็นไปตามข้อกำหนด (การนับตัวอักษรในรหัสตามที่กำหนดฉันได้รับ 34 แต่ช่องว่างทั้งสองอาจถูกลบออกอย่างปลอดภัยทำให้มีความยาว 32)
celtschk


4

Java (67 ตัวอักษร)

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

โปรดทราบว่านี่เป็นการหลีกเลี่ยงการสูญเสียความสำคัญโดยการเพิ่มตัวเลขในลำดับที่ถูกต้อง


นี่คือรหัส C ที่สอดคล้องอย่างสมบูรณ์เช่นกัน ถ้าโพสต์เป็น C, คุณอาจจะเปลี่ยนwhile(--i>0)ไปwhile(i--)และบันทึกตัวอักษร 2
ardnew

1
@ardnew จริง แต่ด้วย C มีเทคนิคที่น่าสนใจมากขึ้นในการเล่น ...
Peter Taylor



3

C (GCC) (44 ตัวอักษร)

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

นั่นคือ 41 ตัวอักษร แต่ก็ต้องมีการคอมไพล์ด้วย-O2เพื่อให้เครื่องมือเพิ่มประสิทธิภาพเพื่อกำจัดการเรียกซ้ำหาง สิ่งนี้ยังขึ้นอยู่กับพฤติกรรมที่ไม่ได้กำหนดด้วยความเคารพต่อลำดับที่++ถูกดำเนินการ ขอบคุณ ugoren ที่ชี้เรื่องนี้ออกมา ฉันทดสอบกับ gcc 4.4.3 ภายใต้ Linux 64 บิต

โปรดทราบว่าหากเครื่องมือเพิ่มประสิทธิภาพจัดเรียงผลรวมนั้นจะเพิ่มจากจำนวนที่เล็กที่สุดเพื่อหลีกเลี่ยงการสูญเสียความสำคัญ

โทรp()มา


โทร recursive ของคุณคือไม่q() p()และฉันไม่คิดว่า-O2ควรนับ (แต่ถ้าคุณนับเป็น 4 ตัวอักษรเพราะพื้นที่ที่ต้องการ)
ugoren

นอกจากนี้: 1. gcc 4.1.1 ไม่ปรับการเรียกซ้ำให้เหมาะสม (และฉันไม่เห็นว่าจะทำได้) ดังนั้นสแต็กล้น 2. p(0)มันควรจะเรียกว่าเป็น 3. return++i...บันทึกถ่านโดย 4. สอง++iทำให้พฤติกรรมไม่ได้กำหนด
ugoren

@ugoren ขอบคุณสำหรับความคิดเห็นของคุณ ตามลำดับ: q- นั่นจะสอนให้ฉันตรวจสอบอีกครั้งหลังจากเปลี่ยนชื่อ ฉันคิดว่าฉันปฏิบัติตามปกติในการนับ-O2เป็น 3 ตัวอักษร แต่เราสามารถเปิดเมตาถ้าคุณต้องการ; meta.codegolf.stackexchange.com/questions/19เป็นการสนทนาที่เกี่ยวข้องเท่านั้นที่ฉันสามารถค้นหา ฉันได้เพิ่มรุ่นของ GCC p()ซึ่งผมใช้และที่ช่วยให้ผมเรียกว่าเป็น การบันทึกถ่านหยุดการเพิ่มประสิทธิภาพและให้ segfault ผมจะชี้แจงว่าฉันใช้พฤติกรรมที่ไม่ได้กำหนดตามmeta.codegolf.stackexchange.com/questions/21
ปีเตอร์เทย์เลอร์

ฉันได้เพิ่มคำตอบสำหรับคำถามเมตาเกี่ยวกับการตั้งค่าสถานะ เกี่ยวกับp()- คุณแน่ใจหรือไม่ว่าการโทรp()จากบริบทใด ๆ หรือเป็นเพียงแค่สิ่งที่เกิดขึ้นกับสแต็คในการทดสอบของคุณ?
ugoren

@ugoren บางทีฉันอาจโชคดีอย่างต่อเนื่อง แม้ว่าฉันจะเรียกมันสองครั้งติดต่อกัน แต่สิ่งที่สองยังคงส่งกลับค่าที่ถูกต้อง gcc ดูเหมือนจะสร้างโค้ดที่แตกต่างกันเล็กน้อยสำหรับp()vs p(0)แต่ฉันไม่รู้ว่ามันทำงานอย่างไรและฉันไม่ใช่โปรแกรมเมอร์ C จริงๆ
Peter Taylor

3

J, 26 ตัวอักษร

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

ย้ายจากลำดับ 100 รายการไปเป็น 1e6 รายการ ตอนนี้มันเป็นรหัสที่ติดแท็กและสามารถคัดลอกจากเบราว์เซอร์ไปยังคอนโซลได้โดยไม่มีข้อผิดพลาด

+/+/_2((4 _4)&%)\>:+:i.1e6

3
-/4%>:2*i.1e6- 13 ตัวอักษร (ขอบคุณ b_jonas ใน #jsoftware ที่ทำให้ฉันรู้ว่ามัน-/ทำงานเพื่อคำนวณผลรวมกับเครื่องหมายสลับ [นี่เป็นเพราะตัวดำเนินการทั้งหมดใน J มีความสำคัญเท่ากันและมีความสัมพันธ์ทางขวาดังนั้น-/ 1 2 3 4<=> 1 - (2 - (3 - 4))<=> 1 - 2 + 3 - 4]
FireFly

มันเรียบร้อยและยอดเยี่ยมเป็นสองเท่า หรือแม้กระทั่ง 2 ^ 10 ยอดเยี่ยมมาก!
fftw

@FireFly นั่นช่างสวยงาม
โยนาห์

2

Javascript - 33 ตัวอักษร

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

การโทรpผ่านจำนวนคี่บวกxและจะคำนวณ Pi ด้วย(x-1)/2คำศัพท์


2

Ruby - 82 ตัวอักษร

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)

ลองใช้: https://repl.it/LQ8w

วิธีการใช้ชุดที่กำหนดทางอ้อมโดยใช้วิธีการเร่งความเร็วเชิงตัวเลข ผลลัพธ์ที่ได้คือ

pi ≈ 3.14159265161

เมื่อเทียบกับ

pi = 3.14159265359

มันเริ่มต้นด้วย

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

แล้วเนื่องจากสิ่งนี้สลับกันเราจึงสามารถเร่งการบรรจบกันโดยใช้

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

และมันใช้ซ้ำ:

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

และเพื่อความเรียบง่าย, f(n) = f(n,n).


Ruby - 50 ตัวอักษร

หากคุณไม่คิดที่จะทำงานนานมากคุณก็สามารถใช้งานได้

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

หรือ

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

1

C, 69 ตัวอักษร

float p,b;void main(a){b++<9e6?p+=a/b++,main(-a):printf("%f\n",4*p);}
  • เรียกใช้โดยไม่มีพารามิเตอร์บรรทัดคำสั่ง (เช่นนั้น aถูกเตรียมข้อมูลเบื้องต้นเป็น 1)
  • จะต้องรวบรวมด้วยการปรับให้เหมาะสม
  • void mainแปลกและไม่ได้มาตรฐาน แต่ทำให้ทุกอย่างทำงาน หากไม่มีการเรียกซ้ำการเรียกใช้จะเป็นการเรียกใช้จริงซึ่งนำไปสู่การโอเวอร์โฟลว์แบบสแต็ก อีกทางเลือกหนึ่งคือการเพิ่มreturnอีกทางเลือกหนึ่งคือการเพิ่ม
  • 4*สามารถบันทึกอักขระสองตัวได้หากรันด้วยพารามิเตอร์บรรทัดคำสั่งสามตัว

คุณสามารถร่นที่int main(a)หรือแม้กระทั่งmain(a), GCC เพียง แต่ช่วยให้คำเตือน และมันจะให้คำเตือนvoid mainต่อไปและอาจเป็นเพราะคุณมีข้อโต้แย้งเพียงข้อmainเดียว
nyuszika7h

1

Clojure - 79 ตัวอักษร

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

สิ่งนี้จะสร้างฟังก์ชั่นที่ไม่มีข้อโต้แย้งซึ่งจะคำนวณการลอยที่ใกล้เคียงกับ pi อย่างถูกต้องกับทศนิยมห้าตำแหน่ง โปรดทราบว่านี้ไม่ได้ผูกฟังก์ชั่นเป็นชื่อเช่นpiดังนั้นรหัสนี้จะต้องได้รับการประเมินในสถานที่ที่evalเป็น(<code>)หรือผูกไว้กับชื่อซึ่งในกรณีการแก้ปัญหาเป็น

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

82 ตัวอักษร

เกี่ยวกับ

(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

1

PHP - 56 55 ตัวอักษร

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

ฉันไม่รู้ว่าฉันจะทำให้เล็กลงได้โดยไม่ทำลายกฎของอัลกอริทึม


1
แล้ว 45 ล่ะ <?for(;1e6>$j;)$p+=($i=-$i|4)/~-$j+=2;echo$p;
โม่

ฉันพยายามที่จะเกิดขึ้นกับที่ แต่ไม่สามารถรับ ops bitwise ในการทำงาน ขอบคุณสำหรับคำแนะนำ!
TwoScoopsofPig

คุณสามารถลบเครื่องหมายอัฒภาคสุดท้ายเพื่อบันทึก 1 อักขระ
nyuszika7h

1

Perl - 43 39 ตัวอักษร

ไม่แน่ใจว่ากฎเกี่ยวกับรูทีนย่อยที่ไม่ระบุชื่อ แต่นี่คือการใช้งานอื่นโดยใช้การสร้างซีรีส์ของ @ FireFly

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

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


0

Java - 92 84 ตัวอักษร

ฉันไม่สามารถเอาชนะผลลัพธ์ของปีเตอร์เทย์เลอร์ได้ไกล แต่นี่คือของฉัน:

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

เวอร์ชันที่ไม่ถูกปรับแต่ง:

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

แก้ไข: บันทึกสองสามตัวอักษรโดยใช้โอเปอร์เรเตอร์


0

Python - 56 ตัวอักษร

ฉัน, งูหลามฟูของฉันไม่แข็งแรงพอ ฉันไม่เห็นทางลัดอีกต่อไป แต่อาจมีนักกอล์ฟที่มีประสบการณ์มากกว่าสามารถหาสิ่งที่จะตัดแต่งได้ที่นี่

t=s=0
k=i=1
while t<1e6:t,s,i,k=t+1,k*4./i+s,i+2,-k

คุณสามารถใช้ Python 3 เพื่อบันทึกหนึ่งไบต์สำหรับส่วนทศนิยม ( 4.-> 4) ในข่าวอื่น ๆ ฉันเพิ่งพบกรณีที่ Python 3 เต้น Python 2 ใน code golf จริง ๆ !
nyuszika7h

0

Ruby - 54 ตัวอักษร

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

ฉันลองคอนโซลครั้งแรก

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

63 ตัวอักษร


คุณสามารถบันทึกไบต์โดยใช้แทนdef a; def a()
nyuszika7h

อีกอันหนึ่งโดยการลบเครื่องหมายอัฒภาคสุดท้าย
nyuszika7h

0

Perl (ตัวอักษร 76 ตัว)

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

(ผลลัพธ์: 3.14159052)

ไม่ใช่ทางออกที่สั้นที่สุด แต่อาจน่าสนใจ มันเป็นเรขาคณิต ฉันคำนวณพื้นที่ใต้วงกลม

ฉันเข้าใกล้อีกวิธีตลก แต่มันช้ามาก มันนับจำนวนจุดที่ไม่ต่อเนื่องในสี่เหลี่ยมจัตุรัสที่ต่ำกว่าหนึ่งในสี่ของวงกลมและคำนวณ pi จากมัน:

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

คาดว่าจำนวนการวนซ้ำเป็นอาร์กิวเมนต์บรรทัดคำสั่ง ที่นี่คุณสามารถดูว่าเวลาทำงานเกี่ยวข้องกับความถูกต้องอย่างไร ;)

$ 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





0

SQL, 253 ไบต์

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

ฉันจะให้ซอฟแวร์ SQL, แต่มันวนมากเกินไปที่จะหาเศษส่วน 1/3/1/7 1/7 และลึกเกินไปและให้ข้อผิดพลาด lol อย่างไรก็ตามหากคุณเปลี่ยน@B<100000เป็น1000มันจะทำงาน (เห็นได้ชัดว่าไม่ใช่จำนวนหลักของความแม่นยำเท่ากัน)


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.