ค้นหาทศนิยมตำแหน่งที่ n ของ pi


33

มี30 ความท้าทายที่ทุ่มเทให้กับ piแต่ไม่มีใครขอให้คุณค้นหาทศนิยมที่ n ดังนั้น ...

ท้าทาย

สำหรับจำนวนเต็มใด ๆ ในช่วงของการ0 <= n <= 10000แสดงทศนิยมทศนิยมอันดับที่ n ของ pi

กฎระเบียบ

  • ทศนิยมเป็นตัวเลขทุกหลัง 3.
  • โปรแกรมของคุณอาจเป็นฟังก์ชั่นหรือโปรแกรมเต็มรูปแบบ
  • คุณต้องแสดงผลลัพธ์ในฐาน 10
  • คุณอาจได้รับnจากวิธีการอินพุตที่เหมาะสม (stdin, input (), พารามิเตอร์ฟังก์ชัน, ... ) แต่ไม่ฮาร์ดโค้ด
  • คุณสามารถใช้การจัดทำดัชนีแบบ 1ถ้าเป็นของภาษาที่คุณเลือก
  • คุณไม่ได้มีการจัดการกับข้อมูลที่ไม่ถูกต้อง ( n == -1, n == 'a'หรือn == 1.5)
  • อนุญาตให้สร้างบิวด์อินได้ถ้าพวกมันรองรับทศนิยมอย่างน้อย 10k
  • รันไทม์ไม่สำคัญเนื่องจากเป็นรหัสที่สั้นที่สุดและไม่ใช่รหัสที่เร็วที่สุด
  • นี่คือรหัสที่สั้นที่สุดในหน่วยไบต์ชนะ

กรณีทดสอบ

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

สำหรับการอ้างอิงนี่คือตัวเลข 100k แรกของ pi


Built-in? เช่นstr(pi())[n+2]
primo

6
ที่อยู่ใกล้เป้าหมายล่อ IMO จะคำนวณตัดทอนบาทเงินก้อนอำนาจของปี่ (overloads พารามิเตอร์หรือมันก็จะมีความแตกต่างแน่นอนนำไปใช้กับความท้าทายนี้) ส่งปี่แม่นยำ (เพิ่มดัชนีและยับยั้งการพิมพ์บางส่วน) และการเข้ารหัสหน้าต่าง Pi
Peter Taylor

3
@suever ofcourse! กฎนั้นเป็นเพียงการชี้ให้เห็นว่า 10k เป็นขั้นต่ำที่โปรแกรมของคุณควรจะสามารถจัดการได้
Bassdrop Cumberwubwubwub

4
ฉันขอแนะนำให้เพิ่ม f (599) ในกรณีทดสอบเนื่องจากอาจทำให้ผิดได้ง่าย (คุณต้องการความแม่นยำพิเศษประมาณ 3 ทศนิยม)
aditsu

2
นอกจากนี้ f (760) = 4 ซึ่งเริ่มต้นลำดับที่ 4 999999 8 นั้นง่ายต่อการปัดเศษอย่างไม่ถูกต้อง
Anders Kaseorg

คำตอบ:


22

05AB1E, 3 ไบต์

žs¤

อธิบาย

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

ลองออนไลน์

ใช้การจัดทำดัชนีแบบอิง 1
รองรับได้สูงสุด 100k หลัก


Pi ถึง n หลักไม่ได้ใช่ไหม
busukxuan

7
@ busukxuan ไม่มันใช้ค่าคงที่ที่กำหนดไว้ล่วงหน้าของ pi ถึง 100k หลักและดึง N ของพวกเขา
Emigna

4
@Emigna นั่นมันมีประโยชน์มาก ทางออกที่ดี
Suever

2
สั้นและคมชัด PCG ที่ดีที่สุด
Xylius

16

Python 2, 66 ไบต์

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

อินพุตถูกนำมาจาก stdin


ตัวอย่างการใช้งาน

$ 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

ระมัดระวังเกี่ยวกับการใช้ n ในอัลกอริทึม ... ผลลัพธ์สำหรับ 599 ควรเป็น 2 ไม่ใช่ 1 นอกจากนี้คุณอาจต้องการระบุว่าคุณกำลังใช้ python 2
aditsu

@aditsu อัปเดตแล้ว ยืนยันแล้วสำหรับn ≤ 1,000ทั้งหมด
primo

1
หากคุณใช้nเป็นอินพุตบวก 9 คุณสามารถหลีกเลี่ยงการ parens
xnor

@xnor d'oh ขอบคุณ;)
primo

2
ตัวเลขสองสามตัวแรกที่สร้างโดยอัลกอริทึมนี้คือ '3.141596535897932 ... ' ซึ่งหายไป '2' ระหว่างตำแหน่ง 5 และ 6 ทำไม? เพราะนั่นคือเมื่อโอเปอเรเตอร์ `` Python 2 เริ่มต้นต่อท้ายLสตริง
Anders Kaseorg

11

Bash + coreutils, 60 49 ไบต์

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

ปรับปรุงโดยเดนนิส ขอบคุณ!

ดัชนีเป็นแบบอิงฐานเดียว


11

Python 2, 73 71 73 ไบต์

ขอบคุณ @aditsu สำหรับการเพิ่มคะแนนของฉัน 2 ไบต์

ในที่สุดอัลกอริทึมที่สามารถเสร็จสมบูรณ์ภายใน 2 วินาที

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]

ไอเดียมัน!

ใช้สูตรpi = 4*arctan(1)ขณะคำนวณarctan(1)โดยใช้ชุดเทย์เลอร์


ค่อนข้างเร็ว แม้ว่าการจัดทำดัชนี 1 นั้นไม่ได้มีมาจาก python ครั้งสุดท้ายที่ฉันเรียกคืน (เป็นที่ยอมรับฉันได้รับการใช้งานในขณะที่) f=lambda n:...ฉันทามติเป็นฟังก์ชั่นที่จะต้องมีการกำหนดไว้เช่น
primo

2
แลมบ์ดาเกือบทุกตัวจะไม่ระบุตัวตน (คุณสามารถค้นหาคำตอบใน Python ในเว็บไซต์นี้)
Leaky Nun

โพสต์เมตาที่เกี่ยวข้อง น่าจะเป็นในการละเมิดกฎข้อที่ 1 และ 3 (หลังจากใช้รหัสของคุณมีวิธีการจับภาพการอ้างอิงฟังก์ชันไม่มีการกำหนดฟังก์ชันจะต้องมีการพิมพ์ออกมาสำหรับแต่ละอินพุท ( (lambda n:`p`[n+1])(1), (lambda n:`p`[n+1])(2), ... ).
พรีโม่

1
คุณไม่สามารถเรียกใช้รหัสโดยตรง มันคล้ายกับการวางimportคำสั่งล่วงหน้าเพียงแค่นี้ทำให้ตัวแปรทั่วโลกบางอย่างไว้ล่วงหน้า
Leun Nun

i=3 while a:a=i/2*a/i;p+=a;i+=2สำหรับ 4.
primo

7

MATL, 11 10 ไบต์

บันทึก 1 ไบต์ขอบคุณ @Luis

YPiEY$GH+)

โซลูชันนี้ใช้การจัดทำดัชนีแบบ 1 ฐาน

ลองออนไลน์

กรณีทดสอบทั้งหมด

คำอธิบาย

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 โอ้ใช่แล้วฉันเดาว่าเอาต์พุตจะเป็นสตริงอยู่แล้ว Doh!
Suever

@ LuisMendo โอ้ฉันไม่เคยคิดอย่างนั้นจริงๆ ฉันมักจะใช้YPในการทดสอบกล่องเครื่องมือสัญลักษณ์
Suever

YP อนุญาตจริงหรือไม่ คำถามบอกว่าได้รับอนุญาตหากรองรับ <= 10k หลัก
busukxuan

@Suever OP ระบุว่า "ไม่เกิน" มากกว่า "อย่างน้อย" เพื่อความเข้าใจของฉันซึ่งหมายถึงการสนับสนุน> 10k เป็นสิ่งต้องห้าม
busukxuan

@Suever ใช่ฉันคิดว่าฉันอาจจะเป็นเช่นนั้นฉันไม่สามารถต้านทานการทำมันได้ฮ่า ๆ ฉันลบคำตอบ Sage ของฉันเพราะสิ่งนั้น
บุษบาซวน


5

ปราชญ์, 32 25 ไบต์

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

คำตอบแรกของฉันในภาษาประเภทนี้

nปัดเศษpiเป็น 17775 ตัว


1
คุณต้องการการprintโทรมิฉะนั้นนี่คือตัวอย่างที่ใช้งานได้ใน REPL เท่านั้น
Mego

สิ่งนี้ใช้ได้กับ (ในทางทฤษฎี) อินพุตใด ๆ :lambda d:`n(pi,digits=d+5)`[-4]
Mego

2
@ หากไม่มี "99999" ทำงานอยู่
busukxuan

1
@Mego แต่แล้วจะมีอีกต่อไป "9" วิ่ง ฉันไม่แน่ใจว่าการเพิ่มความยาวเป็นสองเท่าสามารถทำให้เป็นสากลได้หรือไม่ แต่ฉันคิดว่าไม่สามารถทำได้เนื่องจากทฤษฎีบท Infinite Monkey: en.wikipedia.org/wiki/Infinite_monkey_theorem
busukxuan

1
@busukxuan หากคุณจำลองตัวเลขที่ไม่มีการเข้ารหัสของπเป็นแบบสุ่มคุณคาดหวังว่าการรันนาน 9 ชั่วโมงโดยพลการ (และเราไม่มีเหตุผลที่จะคาดหวังว่า real จริงจะแตกต่างกันแม้ว่าเราจะไม่ได้พิสูจน์สิ่งนี้) แต่คุณคาดหวัง ทำงาน 9 วินาทีตราบใดที่ตำแหน่งมีความน่าจะเป็นที่หายไปเล็กน้อย (แต่เราไม่ได้พิสูจน์ว่าจริง real ไม่ได้ทำงานโดยไม่คาดคิด) เราพบการวิ่งอย่างน้อยเก้าเก้าวินาทีซึ่งฉันคิดว่าเพียงพอที่จะทำลาย[-8]ข้อเสนอ
Anders Kaseorg


4

Mathematica, 23 21 ไบต์

⌊10^# Pi⌋~Mod~10&

SageMath ขนาด 24 ไบต์

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

@LLAMAMYYP ฉันลองแล้ว แต่ Mathematica นั้นต้องการช่องว่างระหว่างPiและ(หรือระหว่าง#และถ้าการคูณถูกพลิก) ดังนั้นการบันทึกจะหายไป
Anders Kaseorg

ที่จริงแล้วมันใช้งานได้ใน Mathematica Online (ฉันใช้เวอร์ชั่นคอนโซล) ดังนั้นฉันจะเอามันฉันเดา
Anders Kaseorg

4
คำตอบเหล่านี้ควรแยกจากกัน แม้ว่าพวกเขาจะใช้กลยุทธ์เดียวกันพวกเขาไม่มีที่ไหนใกล้เคียงกับภาษาเดียวกัน
Mego

@ Mego นโยบายที่ฉันพบไม่ได้กล่าวคำตอบในภาษาต่างๆไม่สามารถนับได้ว่าคล้ายกันมาก (คำตอบที่แนะนำว่าไม่ได้รับการยอมรับ) คุณกำลังอ้างถึงนโยบายอื่นหรือเพียงแค่การตั้งค่าหรือไม่?
Anders Kaseorg

3

J , 19 15 ไบต์

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

รับจำนวนเต็มnและส่งออก n THหลักของปี่ ใช้การทำดัชนีแบบ zero-based ที่จะได้รับn THหลักคำนวณครั้งปี่ 10 n +1ใช้พื้นของค่าที่แล้วเอามันแบบโมดูโล 10

การใช้

อินพุตเป็นจำนวนเต็มแบบขยาย

   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

บนเครื่องของฉันใช้เวลาประมาณ 18 นาทีในการคำนวณ 10,000 thหลัก

คำอธิบาย

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 ไบต์

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

ดังนั้นอย่างที่คุณสามารถบอกได้ฉันไม่รู้ว่าฉันกำลังทำอะไรอยู่ เรื่องนี้จบลงด้วยความขบขันมากกว่าอะไร ฉันต้องการ "pi ถึง n หลัก" ของ Google และจบลงด้วยการหน้าวิกิพีเดียสูตร Bailey-Borwein-Plouffe ฉันรู้ว่าแคลคูลัส (?) เพิ่งอ่านสูตรไม่ได้ฉันจึงสามารถแปลมันเป็น Clojure ได้

การแปลนั้นไม่ยาก ความยากลำบากมาจากการใช้งานที่มีความแม่นยำถึง n-ตัวเลขตั้งแต่สูตรต้อง(Math/pow 16 precision); ซึ่งใหญ่โตเร็วจริงๆ ฉันจำเป็นต้องใช้BigDecimalทุกที่เพื่อใช้ในการทำงานซึ่งจริงๆแล้วสิ่งต่าง ๆ ป่องขึ้น

Ungolfed:

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

ไม่จำเป็นต้องพูดฉันแน่ใจว่ามีวิธีที่ง่ายกว่าถ้าคุณรู้คณิตศาสตร์

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

ฉันรู้ในภายหลังว่าตัวดำเนินการมาตรฐานใช้งานได้จริงกับทศนิยมขนาดใหญ่ดังนั้นทางลัดที่ด้านบนจึงไม่จำเป็น ฉันเมาแก้ไขในบางจุด นั่นอาจจะทำให้ล้มลง ~ 50 ไบต์
Carcigenicate

2

Clojure 253 ไบต์

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

คำนวณตัวเลข pi โดยใช้สูตรนี้ ต้องกำหนดมาโครใหม่with-precisionเนื่องจากใช้บ่อยเกินไป

คุณสามารถดูผลลัพธ์ได้ที่นี่: https://ideone.com/AzumC3 1,000 และ 10,000 ใช้เวลาเกินกว่าที่กำหนดไว้สำหรับ ideone, ยักไหล่


2

Python 3 , 338 ไบต์

การใช้งานนี้ขึ้นอยู่กับอัลกอริทึม Chudnovskyซึ่งเป็นหนึ่งในอัลกอริทึมที่เร็วที่สุดในการประมาณค่า pi สำหรับการคำนวณซ้ำแต่ละครั้งจะมีการประมาณตัวเลข 14 หลัก (ดูรายละเอียดเพิ่มเติมที่นี่ )

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

ลองออนไลน์!


1

Java 7, 262 260 bytes

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

มือสอง@ LeakyNun ของงูหลาม 2 อัลกอริทึม

Ungolfed & รหัสการทดสอบ:

ลองที่นี่

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

เอาท์พุท:

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

1

Smalltalk - 270 ไบต์

อาศัยความเป็นตัวตนtan⁻¹(x) = x − x³/3 + x⁵/5 − x⁷/7 ...และนั่นก็π = 16⋅tan⁻¹(1/5) − 4⋅tan⁻¹(1/239)คือ SmallTalk ใช้เลขจำนวนเต็มความแม่นยำไม่ จำกัด ดังนั้นมันจะทำงานสำหรับอินพุตขนาดใหญ่ถ้าคุณยินดีที่จะรอ!

|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

บันทึกเป็นpi.stและเรียกใช้ในกรณีทดสอบต่อไปนี้ การจัดทำดัชนีเป็นฐานเดียว

$ 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 ไบต์

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

ลองออนไลน์!

การใช้ π/2=Σk=0k!/(2k+1)!!(ตรรกะเดียวกันที่ใช้โดยคำตอบ Python ของ Leaky Nun แต่ต้องขอบคุณไวยากรณ์ของ JS ที่ทำให้สิ่งนี้สั้นลง) อินพุตถูกส่งผ่านไปยังฟังก์ชันเป็น BigInt 2 ไบต์สามารถลบออกได้หากใช้การจัดทำดัชนีแบบที่ 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 ไบต์

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]

ลองออนไลน์!

การใช้ π/4=arctan(1/2)+arctan(1/3). อินพุตถูกส่งผ่านไปยังฟังก์ชันเป็น BigInt 2 ไบต์สามารถลบออกได้หากใช้การจัดทำดัชนีแบบที่ 1:

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 ไบต์

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

กรณีทดสอบ:

> 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

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