Найти десятое десятичного числа пи


33

Уже есть 30 задач, посвященных пи, но ни один не просит вас найти n-ую десятичную дробь, так что ...

Вызов

Для любого целого числа в диапазоне 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

Для справки, вот первые 100 тыс. Цифр числа Пи.


Встроенные модули? напримерstr(pi())[n+2]
primo

6
Ближайшими объектами IMO для вычисления дублирования являются вычисление степеней числа усеченных цифр числа pi (перегружает параметр или это будет просто конечное различие, применяемое к этой задаче), передача точно pi (добавляет индекс и подавляет некоторую печать) и шифрование окна Pi .
Питер Тейлор

3
@ Конечно, конечно! Это правило просто указывает на то, что 10k - это минимум, который ваша программа должна уметь обрабатывать
Bassdrop Cumberwubwubwub

4
Я предлагаю добавить f (599) к тестовым случаям, так как это может быть легко сделать неправильно (вам нужно около 3 десятичных знаков дополнительной точности).
aditsu

2
Также f (760) = 4, с которого начинается последовательность 4 999999 8, легко округлить неправильно.
Андерс Касеорг

Ответы:


22

05AB1E, 3 байта

žs¤

Разъяснения

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

Попробуйте онлайн

Использует индексирование на основе 1.
Поддерживает до 100 тыс. Цифр.


Пи цифрами не округляется?
Busukxuan

7
@busukxuan Нет. Он использовал предопределенную константу от pi до 100 тыс. цифр и извлекал N из них.
Эминья

4
@ Emigna Это очень удобно. Хорошее решение
Сувер

2
Короткий и острый, PCG в своих лучших
проявлениях

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]

Ввод взят из стандартного ввода.


Образец использования

$ 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к строке.
Андерс Касеорг

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:....
Примо

2
Почти каждая лямбда здесь анонимна (вы можете найти ответы на Python на этом сайте)
Leaky Nun

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

1
Вы не можете запустить код напрямую. Это похоже на importпредварительное размещение операторов, просто это делает некоторые глобальные переменные заранее.
Утренняя монахиня

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 О да, я думаю, что вывод уже является строкой. Doh!
Сувер

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

YP действительно разрешено? В вопросе говорится, что разрешено, если он поддерживает <= 10 тыс.
Цифр

@Suever OP заявил «до», а не «по крайней мере». Насколько я понимаю, поддержка> 10k запрещена.
Busukxuan

@ Ну да, я думаю, что могу, но я не могу удержаться от этого, лол. Я удалил свой ответ мудреца только из-за этого.
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
@ Мего нет "99999" работает?
Busukxuan

1
@Mego, но тогда "9" будет еще длиннее. Я не уверен, что удвоение длины может сделать его универсальным, но я думаю, что даже это не может сделать это из-за теоремы о бесконечной обезьяне: en.wikipedia.org/wiki/Infinite_monkey_theorem
busukxuan

1
@busukxuan Если вы моделируете невычисленные цифры числа π как случайные, вы, конечно, ожидаете сколь угодно долгий пробег числа 9 (и у нас нет оснований ожидать, что действительное число π будет другим, хотя мы этого не доказали), но вы ожидаете только пробег 9 с до тех пор, пока его позиция с исчезающе малой вероятностью (хотя, опять же, мы не доказали, что реальное π не ведет себя неожиданно). Мы нашли пробеги по крайней мере девять 9, что, я думаю, достаточно, чтобы сломать [-8]предложение.
Андерс Касеорг


4

Mathematica, 23 21 байт

⌊10^# Pi⌋~Mod~10&

SageMath, 24 байта

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

@LLlAMnYP Я пробовал это, но Mathematica, кажется, требует пробела между Piи (или между, #и если умножение перевернуто), поэтому сохранение исчезает.
Андерс Касеорг

На самом деле это работает в Mathematica Online (я использовал консольную версию), так что я возьму это, я думаю.
Андерс Касеорг

4
Это должны быть отдельные ответы. Хотя они используют одну и ту же стратегию, они далеко не на одном языке.
Mego

@Mego Политика, которую я нашел, не говорит, что ответы на разных языках не могут считаться очень похожими. (Ответ предполагает, что он не был принят.) Вы имеете в виду другую политику или просто предпочтение?
Андерс Касеорг

3

J , 19 15 байт

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

Принимает целое число n и выводит n- ю цифру числа pi. Используется индексирование с нуля. Для того, чтобы получить п - ю цифру, вычислите раз пи 10 п +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 "пи к п цифрам" и оказался на странице Википедии для формулы Бэйли-Борвейна-Плуффа . Зная едва ли исчисление (?), Чтобы прочитать формулу, мне удалось перевести ее на 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)))

Рассчитайте число пи по этой формуле . Необходимо переопределить макрос, так with-precisionкак он используется слишком часто.

Вы можете увидеть вывод здесь: https://ideone.com/AzumC3 1000 и 10000 дублей превышают лимит времени, используемый на ideone, пожимает плечами


2

Python 3 , 338 байт

Эта реализация основана на алгоритме Чудновского , одном из самых быстрых алгоритмов для оценки числа пи. Для каждой итерации приблизительно 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 .

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

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)

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

0

C #, 252 250 байт

d=>{int l=(d+=2)*10/3+2,j=0,i=0;long[]x=new long[l],r=new long[l];for(;j<l;)x[j++]=20;long c,n,e,p=0;for(;i<d;++i){for(j=0,c=0;j<l;c=x[j++]/e*n){n=l-j-1;e=n*2+1;r[j]=(x[j]+=c)%e;}p=x[--l]/10;r[l]=x[l++]%10;for(j=0;j<l;)x[j]=r[j++]*10;}return p%10+1;}

Попробуйте онлайн!

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.