Вычисление усеченных цифр суммы степеней числа Пи


12

Учитывая положительное целое число п вывод суммы первых п десятичных цифр дробной части П п .

Пример ввода и вывода:

1 → 1
2 → 14
3 → 6
4 → 13
5 → 24
50 → 211
500 → 2305
5000 → 22852

Встроенные функции, вычисляющие цифры π или оценивающие либо степенные ряды, либо непрерывные дроби, не допускаются. Применяются стандартные лазейки . Ввод / вывод может быть в удобном формате (стандартный ввод, стандартный вывод, функция ввода / вывода и т. Д.).

Самый короткий код в байтах побеждает.


Можно ли запретить другие функции триггера, которые можно использовать для вычисления числа Пи, но не обязательно напрямую, например, арктангенс или мнимые логарифмы? Кроме того, существует ли верхний предел для n, после которого может произойти сбой?
FryAmTheEggman

@FryAmTheEggman Если эти триггерные функции могут вычислять произвольные цифры числа пи, то да, они запрещены. Ваша программа должна работать теоретически для любого n , но она прощается, если время выполнения или память становятся слишком большими.
orlp

Ответы:


4

Python - 191 байт

t=i=1L;k=n=input();f=2000*20**n;A=range(n+1)
for k in range(2,n):A=[(A[j-1]+A[j+1])*j>>1for j in range(n-k+1)];f*=k
while k:k=(1-~i*n%4)*f/A[1]/i**n;t+=k;i+=2
print sum(map(int,`t`[-n-4:-4]))

~ В 4 раза быстрее версия - 206 байт

t=i=1L;k=n=input();f=2000*20**n;A=[0,1]+[0]*n
for k in range(1,n):
 f*=k
 for j in range(-~n/2-k+1):A[j]=j*A[j-1]+A[j+1]*(j+2-n%2)
while k:k=(1-~i*n%4)*f/A[1]/i**n;t+=k;i+=2
print sum(map(int,`t`[-n-4:-4]))

Ввод взят из стандартного ввода. Вывод для n = 5000 занимает примерно 14 секунд со вторым сценарием (или 60 секунд с первым).


Пример использования:

$ echo 1 | python pi-trunc.py
1

$ echo 2 | python pi-trunc.py
14

$ echo 3 | python pi-trunc.py
6

$ echo 4 | python pi-trunc.py
13

$ echo 5 | python pi-trunc.py
24

$ echo 50 | python pi-trunc.py
211

$ echo 500 | python pi-trunc.py
2305

$ echo 5000 | python pi-trunc.py
22852

Используемая формула следующая:

где A n - это n- й переменный номер , который можно формально определить как число чередующихся перестановок в наборе размера n (см. также: A000111 ). Альтернативно, последовательность может быть определена как композиция чисел касательных и секущих чисел ( A 2n = S n , A 2n + 1 = T n ), подробнее об этом позже.

Малый поправочный коэффициент c n быстро сходится к 1, когда n становится большим, и определяется как:

Для n = 1 это равносильно оценке ряда Лейбница . Приближая π к 10 ½ , количество необходимых терминов можно рассчитать как:

который сходится (округляется) до 17 , хотя меньшие значения n требуют значительно большего.

Для вычисления A n существует несколько алгоритмов и даже явная формула, но все они квадратичны по n . Первоначально я кодировал реализацию алгоритма Зайделя , но он оказывается слишком медленным, чтобы быть практичным. Каждая итерация требует сохранения дополнительного слагаемого, и слагаемые увеличиваются по величине очень быстро («неправильный» тип O (n 2 ) ).

Первый сценарий использует реализацию алгоритма, первоначально заданного Кнутом и Бакгольцем :

Пусть T 1, k = 1 для всех k = 1..n

Последующие значения T задаются рекуррентным соотношением:

T n + 1, k = 1/2 [ (k - 1) T n, k-1 + (k + 1) T n, k + 1 ]

Тогда A n определяется как T n, 1

(см. также: A185414 )

Хотя это и не указано явно, этот алгоритм рассчитывает и Касательные Числа и Числа Секанта одновременно. Второй сценарий использует вариант этого алгоритма Брента и Циммермана , который вычисляет либо T, либо S , в зависимости от четности n . Улучшение является квадратичным по n / 2 , следовательно, улучшение в ~ 4 раза.


1
Отличное объяснение математики за ваш ответ.
Рыцарь логики

3

Python 2, 246 байт

Я применил аналогичный подход к своему ответу на Расчет π с квадратичной сходимостью . Последняя строка принимает N-ю степень числа пи и суммирует цифры. Тест N = 5000 занимает минуту или около того.

from decimal import*
d=Decimal
N=input()
getcontext().prec=2*N
j=d(1)
h=d(2)
f=h*h
g=j/h
a=j
b=j/h.sqrt()
t=j/f
p=j
for i in bin(N)[2:]:e=a;a,b=(a+b)/h,(a*b).sqrt();c=e-a;t-=c*c*p;p+=p
k=a+b
l=k*k/f/t
print sum(map(int,`l**N`.split('.')[1][:N]))

Некоторые тесты:

$ echo 1 | python soln.py
1
$ echo 3 | python soln.py
6
$ echo 5 | python soln.py
24
$ echo 500 | python soln.py
2305
$ echo 5000 | python soln.py
22852

Негольфированный код:

from decimal import *
d = Decimal

N = input()
getcontext().prec = 2 * N

# constants:
one = d(1)
two = d(2)
four = two*two
half = one/two

# initialise:
a = one
b = one / two.sqrt()
t = one / four
p = one

for i in bin(N)[2:] :
    temp = a;
    a, b = (a+b)/two, (a*b).sqrt();
    pterm = temp-a;
    t -= pterm*pterm * p;
    p += p

ab = a+b
pi = ab*ab / four / t
print sum(map(int, `pi ** N`.split('.')[1][:N]))

Строка 8, вы можете обратиться a=jи p=jк a=p=jIIRC. Может быть.
Элиас Беневедес

Благодарю. Для этого кода есть больше оптимизаций игры в гольф, но он не будет конкурентоспособным без переписывания с использованием алгоритма без десятичной дроби.
Рыцарь логики

1

Пиф, 33

s<>j^u+/*GHhyHy^TyQr*TQ0ZQT_y*QQQ

Основываясь на этом ответе isaacg . Возможно, будет в гольф больше. Медленный.

s<>j            Digit sum of...
  ^                 
    u               Evaluate pi = 2 + 1/3*(2 + 2/5*(2 + 3/7*(2 + 4/9*(2 + ...))))
      +
        /
          *GH
          hyH
        y^TyQ       Except we generate a large integer containing 2n digits,
                    rather than a fraction.
      r*TQ0         Experimentally verified that 10*n iterations will give enough
                    precision for 2n digits (# digits correct grows faster than 2n).
      Z
    Q               To the nth power.
  T_y*QQQ         Get the last 2n^2 digits (all the fractional digits) and get the
                  first n fractional digits.

1
Этот ответ действительно нуждается, по крайней мере, в достаточном объяснении, чтобы оправдать, что он вычисляет достаточно цифр, чтобы получить правильный ответ.
Питер Тейлор

@PeterTaylor Завтра я добавлю объяснение, как раз собираюсь ложиться спать.
orlp

Каждая итерация производит один правильный бит (см. Приложение A ). 2n цифр должно потребовать ~ 6,64n итераций.
Примо
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.