ส่ง Pi ... อย่างแม่นยำ


11

ต่อจากการประมาณค่า Monte Carlo ของ Piความท้าทายนี้คือการสร้างรหัสที่สั้นที่สุดสำหรับค่าคงที่ Pi ยกเว้นที่นี่รหัสของคุณจะต้องส่งออกตัวเลข pi ติดต่อกันตลอด

นี่คือรหัสกอล์ฟดังนั้นการส่งที่สั้นที่สุด (เป็นไบต์) ชนะยกเว้นว่าจะต้องส่งออก 10,000 หลักแรกในเวลาน้อยกว่า 10 วินาทีบนพีซีที่เหมาะสมและจะต้องไม่สิ้นสุด

คุณไม่สามารถใช้ฟังก์ชั่น Pi หรือ Trig ในตัวได้


ลบขีด จำกัด ฮาร์ดในขนาดรหัส


1
คุณทวีตโดยหมายความว่ารหัสจะต้องมีความยาวน้อยกว่า 140 ตัวอักษรหรือไม่
Ypnypn

5
ปัญหาในตัวเองดูเหมือนจะท้าทายโดยไม่มีข้อ จำกัด ของตัวละคร
BobTheAwesome

1
@ BobTheAwesome ลบข้อ จำกัด จำนวนอักขระตามความต้องการที่เป็นที่นิยม

1
@ mbomb007 ไม่ชัดเจนเลยว่าจุดทศนิยมจะต้องพิมพ์หรือว่าตัวเลขอาจไม่ถูกคั่นด้วย whitespace ความท้าทายเพียงเพื่อ "ส่งออกหลักต่อเนื่องของ pi" จุดทศนิยมไม่ใช่ตัวเลข 3141...คือ - ตัวเลขที่ต่อเนื่องกันของ pi
orlp

1
มันจะดีที่สุดถ้าจำนวนที่พิมพ์ออกมาเป็น Pi ดังนั้นจึงไม่มีช่องว่างระหว่างตัวเลขเช่น มันจะดียิ่งขึ้นถ้ามันรวมจุดทศนิยม

คำตอบ:


7

CJam - 48

3.1o{1YAZ2*:Z#*{_2$*2$2*)/@)\}h*]:+sX2*:X>X<o1}g

สิ่งนี้จะคำนวณπเป็น 2 * ผลรวม (k! / (2k + 1) !!) ด้วยความแม่นยำที่มากขึ้นและมากขึ้นและในทุกขั้นตอนจะพิมพ์ตัวเลขจำนวนหนึ่งจากตำแหน่งที่เหลือ

คุณสามารถลองใช้เวอร์ชันที่แก้ไขแล้วซึ่งทำซ้ำเพียง 8 (ลูปนอก) เท่านั้นและพิมพ์ 512 หลักหรือใช้ล่าม javaสำหรับของจริง บนแล็ปท็อปของฉันมันได้ตัวเลข 16,384 หลักในเวลาประมาณ 6 วินาที

หมายเหตุ: โปรแกรมนี้หิวมากหน่วยความจำ รุ่นที่ประพฤติดีขึ้น แต่อีกเล็กน้อยคือ:

3.1o{T2AZ2*:Z#*1{@2$+@2$*2$2*)/@)1$}g;;sX2*:X>X<o1}g

คำอธิบาย:

3.1o              print 3.1
{…1}g             repeat indefinitely
    1YA           push 1, 2 and 10 (Y=2, A=10)
    Z2*:Z         push Z*2 (Z=3 initially) and store back in Z
    #*            calculate 2*10^Z (2 from the formula and 10^Z for precision)
                  this is the term for k=0, and the earlier 1 represents k
    {…}h          do-while
                  at each iteration, the stack contains: terms, k, last-term
        _2$*      copy the previous term and k and multiply them
        2$2*)/    divide the previous number by 2*k+1
                  this is the current term of the series
        @)\       increment k and move it before the current term
                  the current term now serves as the loop condition
                  so the loop terminates when the term becomes 0
    *             multiply k and the last term (0), to get rid of k
    ]:+s          put all the terms in an array, add them and convert to string
                  we obtain an approximation of π*10^Z
    X2*:X         push X*2 (X=1 initially) and store back in X
    >X<o          print X digits starting from the X position

8

Python ขนาด 138 ไบต์

q,r,t,i=1,180,60,2
while 1:u,y=27*i*(i+1)+6,(q*(27*i-12)+5*r)//(5*t);print(y,end="");q,r,t,i=10*q*i*(2*i-1),10*u*(q*(5*i-2)+r-y*t),t*u,i+1

การดำเนินงานของhttp://www.cs.ox.ac.uk/jeremy.gibbons/publications/spigot.pdf


เอาชนะฉันให้ได้ภายใน 5 นาที ..... :)
Maltysen

มันเยี่ยมมาก อย่างไรก็ตามฉันก็หวังว่าตัวเลขทั้งหมดจะอยู่ในหนึ่งบรรทัด กล่าวอีกนัยหนึ่งว่าผลลัพธ์จะดูเหมือน Pi

2
@ Lembik ฉันเปลี่ยนคำตอบของฉัน - อีกต่อไป 7 ไบต์ แต่ตอนนี้ทั้งหมดในบรรทัดเดียว
orlp

5

GolfScript (81 ตัวอักษร)

1:i:^3{3i):i*(.(*3*.@*.5*3$27i*12-*+@^*:^5*/.print^*2$5i*2-*--\10*i*2i*(*\10*.}do

การสาธิตออนไลน์ (ซึ่งช้ากว่าเดสก์ท็อปที่เหมาะสมและมีการเปลี่ยนแปลงรหัสเล็กน้อยเพื่อวนซ้ำจำนวนครั้ง)

แน่นอนว่าฉันใช้อัลกอริธึมเดือยที่ฉันพูดถึงในความคิดเห็นก่อนหน้านี้ แต่ฉันใช้เวลาสักครู่ในการเล่นกอล์ฟเพื่อความพึงพอใจของฉัน อัลกอริธึมที่นำเสนอในกระดาษของชะนีคือ (pseudocode)

q = 1; r = 180; t = 60; i = 2
while (true) {
    u = 3*(3*i+1)*(3*i+2)
    y = (q*(27*i-12)+5*r) / (5*t)
    print y
    r += q*(5*i-2)-y*t
    r *= 10*u
    q *= 10*i*(2*i-1)
    t *= u
    i += 1
}

GolfScript ข้างต้นเทียบเท่ากับ (pseudocode)

t = i = q = 1; r = 3
while (true) {
    u = 3*(3*i+1)*(3*i+2)
    i += 1
    r *= u
    t *= u
    y = (q*(27*i-12)+5*r) / (5*t)
    print y
    r -= y*t - q*(5*i-2)
    q *= 10*i*(2*i-1)
    r *= 10
}

ซึ่งบันทึกอักขระบางตัวในการเริ่มต้นและในการจัดการสแต็ก


4

Pyth - 87 85 ไบต์

แปลอีกhttp://www.cs.ox.ac.uk/jeremy.gibbons/publications/spigot.pdf ฉันจะทำ Python แต่ @orlp เอาชนะฉันไปดังนั้นฉันจึงทำ Pyth เล็กพอที่จะใส่ในทวีต

=H3=d1=bd=Gd#K+**hb27b6~b1=H*HK=d*dKJ/+*-*27b12G*5H*5d=H*T-H-*Jd*-*5b2G=G***GTbtybpkJ

มันให้เอาต์พุตไปยัง stdout แม้ว่าจะอยู่ในขั้นตอนต่อเนื่องเนื่องจากบัฟเฟอร์การพิมพ์ที่มาจากการตั้งค่าend=""ในการพิมพ์ ขณะนี้ฉันไม่พิมพ์จุดทศนิยมเนื่องจากข้อมูลจำเพาะระบุว่า "ตัวเลขที่ต่อเนื่องกัน" มันเป็นงานที่ได้รับคะแนนของฉัน

=H3                     Set H to 3
=d1                     Set d to 1
=bd                     Set b to d which is 1
=Gd                     Set G to d which is 1
#                       Infinte Loop
  K                     Set K to
    +**hb27b6           27*b*(b+1)+6
  ~b1                   b+=1
  =H*HK                 H*=K
  =d*dK                 d*=K
  J                     Set J to
    /                   Integer division
      +*-*27b12G*5H     G*(27*b-12)+5*H
      *5d               5*d
  =H                    Set H to
    *T-H-*Jd*-*5b2G     10*(H-(J*d -G*(5*b-2)))
  =G                    Set G to
    ***GTbtyb           G*10*b*(2*b-1)
  pkJ                   Print J with the end as "", not a newline

ลองได้ที่นี่ (หมายเหตุ: เนื่องจากล่ามออนไลน์ให้ผลลัพธ์ที่เสร็จสิ้นเท่านั้นการวนซ้ำไม่สิ้นสุดจึงพิมพ์ครั้งแรก 100 เท่านั้นซึ่งจะเพิ่มขนาดรหัสเมื่อต้องการลองไม่ จำกัด ให้ดาวน์โหลดล่ามท้องถิ่น)

การจับเวลา

ในอินสแตนซ์ไมโครคำนวณคอมพิวเตอร์คลาวด์ของฉันตามเวลา gnu ใช้เวลา: real: 0m2.062sดังนั้นจึงเห็นได้ชัดว่าเร็วพอ


3

สกาลา 599 ไบต์

โค้ดข้างล่างนี้เป็นท่าเรือตรงของรหัสปาสคาลจากภาคผนวก 2 ของจุกอัลกอริทึมสำหรับตัวเลขของพี่ เห็นได้ชัดว่ามีการเล่นกอล์ฟน้อยมาก รหัสจะสร้าง 10,000 หลักในเวลาไม่เกิน 10 วินาทีด้วยpiSpigot(10000)และถ้ามีหน่วยความจำที่ไม่มีที่สิ้นสุดสามารถกำหนดพารามิเตอร์เพื่อสร้างตัวเลขจำนวนมาก แต่ไม่สิ้นสุด ฉันไม่แน่ใจว่านี่เป็นข้อ จำกัด ของปัญหาหรือไม่ดังนั้นโปรดให้ข้อเสนอแนะ

def piSpigot(n: Int): Unit = {
  val len=10*n/3
  var nines=0
  var predigit=0
  val a=Array.fill(len)(2)
  (1 to n).foreach {_=>
    var q=0
    (1 to n).reverse.foreach{i=>
      var x=10*a(i)+q*i
      a(i)=x%(2*i-1)
      q=x/(2*i-1)
    }
    a(1)=q%10
    q/=10
    if (q==9) {
      nines+=1
    } else if (q==10) {
      print(predigit+1)
      1.to(nines).foreach(_=>print(0))
      predigit=0
      nines=0
    } else {
      print(predigit)
      predigit=q
      if (nines!=0) {
        1.to(nines).foreach(_=>print(9))
        nines=0
      }
    }
  }
  println(predigit)
}
piSpigot(10000)

5
nผมคิดว่าความต้องการในการผลิตหลักหมายถึงไม่มีที่สิ้นสุดที่คุณจำเป็นต้องใช้ขั้นตอนวิธีการสตรีมมิ่งมากกว่าหนึ่งซึ่งใช้พารามิเตอร์ ดูเช่นcs.ox.ac.uk/people/jeremy.gibbons/publications/spigot.pdf
Peter Taylor

หน่วยความจำที่ไม่มีที่สิ้นสุดและเวลาที่ไม่มีที่สิ้นสุดควรให้ตัวเลขจำนวนอนันต์

1

Befunge-98 (PyFunge), 120 ไบต์

cf*10p'<20p11>00p1+:30p:::*+39**6+:30g39**c-00g*10gv
>:2*1-*00g*a*^
^:p02*g02p01*a*-*g02\+g01*g00-2*5g03,+*86:/*5g02+*5<

ลองออนไลน์!

นี่คือเส้นเขตแดนในแง่ของ timelimit 10,000 หลักใช้เวลาประมาณ 11 วินาทีในแล็ปท็อปของฉัน แต่ฉันแน่ใจว่าต้องมีพีซี "ที่สมเหตุสมผล" ที่สามารถทำได้เร็วกว่านั้น

อย่างไรก็ตามหากคุณลองใช้กับ TIO โปรดทราบว่าจะไม่ส่งคืนสิ่งใดจนกว่าจะถึงขีด จำกัด เวลา 60 วินาทีเนื่องจากอัลกอริทึมได้รับการออกแบบมาเพื่อดำเนินการต่อไปตลอดไป ในเวลานั้นคุณจะมีตัวเลขมากกว่า 10,000 หลัก

ฉันใช้อัลกอริธึมหัวจุก Jeremy Gibbons ซึ่งฉันคิดว่าเหมือนกับคำตอบอื่น ๆ ที่นี่ อย่างไรก็ตามทราบว่านี้ต้องอาศัยล่ามมีเซลล์หน่วยความจำแม่นยำโดยพลการและการดำเนินการเพียง แต่ฉันรู้ว่าการสนับสนุนที่เป็นPyFunge

คำอธิบาย

cf*10p                     Initialise r to 180.
      '<20p                Initialise t to 60.
           11              Initialise i and q on the stack to 1.

>                          Start of the main loop.
 00p                       Save the current value of q in memory.
    1+:30p                 Increment i and save a copy in memory.      
          :::*+39**6+      Calculate u = 27*(i*i+i)+6.
                     :     Make a duplicate, since we'll need two copies later.

       30g39**c-00g*10gv   Calculate y = (q*(27*i-12)+5*r)/(5*t).
              /*5g02+*5<
        ,+*86:             Convert y to a character so we can output it.

*a*-*g02\+g01*g00-2*5g03   Calculate r = 10*u*(q*(i*5-2)+r-y*t)

         p01               Save the updated r.
     *g02                  Calculate t = t*u
  p02                      Save the updated t.

>:2*1-*00g*a*              Calculate q = 10*q*i*(i*2-1).
^:
             ^             Return to the start of the main loop.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.