Знайдіть п яту десятку пі


33

Уже є 30 завдань, присвячених пі, але жоден з них не просить вас знайти дев'яту десятку, тож ...

Виклик

Для будь-якого цілого числа в діапазоні 0 <= n <= 10000відображення n-ої десяткової точки pi.

Правила

  • Десяткові знаки - це кожне число після 3.
  • Ваша програма може бути функцією або повноцінною програмою
  • Ви повинні вивести результат у базі 10
  • Ви можете отримати nбудь-який відповідний метод введення (stdin, input (), параметри функції, ...), але не жорсткий
  • Ви можете використовувати індексацію на основі 1, якщо вона є рідною для вашої мови
  • Вам не доведеться мати справу з неприпустимим введенням ( n == -1, n == 'a'або n == 1.5)
  • Вбудовані дозволені, якщо вони підтримують щонайменше 10 ккал
  • Виконання не має значення, оскільки мова йде про найкоротший код, а не про найшвидший код
  • Це , найкоротший код у виграші байтів

Тестові справи

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.


Вбудовані? наприкладstr(pi())[n+2]
primo

6
Найближчими цілями IMO є обчислення усіченої цифри підсумовує потужності pi (перевантажує параметр, або це була б лише кінцева різниця, застосована до цього виклику), передача pi точно (додає індекс і пригнічує деяку друк) та шифрування вікна Pi .
Пітер Тейлор

3
@Suever звичайно! Це правило полягає лише в тому, щоб вказати, що 10 кр - це мінімум, з яким має працювати ваша програма
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.
Підтримує до 100 К цифр.


Пі-н-цифр не округляється?
busukxuan

7
@busukxuan Ні. Він використовував заздалегідь задану константу pi до 100k цифр і отримує N з них.
Емінья

4
@Emigna Це дуже зручно. Гарне рішення.
Суєвер

2
Короткий і
різкий

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 ≤ 1000 .
примо

1
Якщо ви вважаєте, nщо вхід плюс 9, ви можете уникнути паронів.
xnor

@xnor d'oh. Спасибі;)
примо

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

Пітон 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:....
примо

2
Практично кожна лямбда тут анонімна (відповіді можна шукати в Python на цьому сайті)
Leaky Nun

Відповідна мета-посада . Здається, в порушенні Правила 1 і 3 (після виконання коду, немає ніякого способу , щоб захопити посилання на функцію, визначення функції має бути набрано для кожного входу ( (lambda n:`p`[n+1])(1), (lambda n:`p`[n+1])(2), ...).
прими

1
Ви не можете запустити код безпосередньо. Це схоже на попереднє розміщення importвисловлювань, тільки що це робить попередньо деякі глобальні змінні.
Leaky Nun

i=3 while a:a=i/2*a/i;p+=a;i+=2для 4.
прим

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 О так, я думаю, вихід вже є рядком. До!
Suever

@LuisMendo О, я ніколи про це не думав. Я завжди використовую YPдля тестування символічний інструментарій
Suever

Чи дозволяється YP насправді? Питання говорить, що це дозволено, якщо він підтримує <= 10k цифр
busukxuan

@Suever OP заявив "до", а не "принаймні". Наскільки я розумію, це означає підтримувати> 10k заборонено.
busukxuan

@Suever Так, я думаю, що я можу бути, тому я не можу чинити опір цьому, хаха. Я видалив свою відповідь Sage саме через це.
busukxuan

6

Mathematica 30 байт

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

Шавлія, 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
@Mego не працює "99999"?
busukxuan

1
@Mego, але тоді буде ще більше "9" пробіжок. Я не впевнений, що подвоєння довжини може зробити це універсальним, але я думаю, що навіть це не може зробити завдяки теоремі нескінченної мавпи: en.wikipedia.org/wiki/Infinite_monkey_theorem
busukxuan

1
@busukxuan Якщо ви будете моделювати необчислені цифри π як випадкові, ви, звичайно, очікуєте довільно довгих пробігів 9s (і у нас немає підстав очікувати, що справжній π буде будь-яким іншим, хоча ми цього не довели), але ви очікуєте лише пробіг 9-х до тих пір, поки його позиція з нині малою ймовірністю (хоча, знову ж таки, ми не довели, що справжній π веде себе несподівано). Ми знайшли пробіжки принаймні дев’яти 9-х, що, на мою думку, достатньо, щоб зламати[-8] пропозицію.
Anders Kaseorg


4

Математика, 23 21 байт

⌊10^# Pi⌋~Mod~10&

SageMath, 24 байти

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

@LLlAMnYP Я спробував це, але, схоже, Mathematica вимагає пробілу між Piі (або між, #і якщо множення перевернуто), тож збереження зникає.
Anders Kaseorg

Насправді це працює в Mathematica Online (я використовував консольну версію), тому я, напевно, візьму його.
Anders Kaseorg

4
Це повинні бути окремі відповіді. Хоча вони використовують одну і ту ж стратегію, вони ніде не знаходяться в одній мові.
Mego

@Mego Політика, яку я знайшов, не говорить, що відповіді різними мовами не можна вважати дуже схожими. (Відповідь, яка говорить про те, що це не прийнято.) Ви маєте на увазі іншу політику чи просто вподобання?
Anders Kaseorg

3

J , 19 15 байт

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

Бере ціле число n і виводить n- ю цифру pi. Використовується індексація на основі нуля. Щоб отримати n- ю цифру, обчисліть pi рази 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

На моїй машині для обчислення 10000- ї потрібно близько 18 хвилин цифри .

Пояснення

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

Отже, як ви, напевно, можете сказати, я поняття не маю, що я роблю. Це в кінцевому підсумку було більш комічним. Я Google "пі на n цифр", і в кінцевому підсумку Вікіпедії для формули Бейлі - Борвейн - Плофф . Знаючи лише ледве обчислення (?), Щоб прочитати формулу, мені вдалося перевести її на Clojure.

Сам переклад був не таким складним. Складність полягала в точності обробки до n-цифр, оскільки формула вимагає (Math/pow 16 precision); який отримує величезний дійсно швидко. Мені потрібно було BigDecimalвсюди використовувати для цього роботу, що насправді роздувала речі.

Безголівки:

(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 1000 та 10000 займає перевищення обмеження часу, що використовується на ideone, знизує плечима


2

Python 3 , 338 байт

Ця реалізація заснована на алгоритмі Чудновського , одному з найшвидших алгоритмів для оцінки 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 байт

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

Використовується алгоритм Python 2 @ LeakyNun .

Невикористаний і тестовий код:

Спробуйте тут.

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

Маленький розмов - 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=к=0к!/(2к+1)!!(така ж логіка, що використовується у відповіді Пітіна Лікі Нун, але завдяки синтаксису 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=арктан(1/2)+арктан(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

Клен, 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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.