pi의 거듭 제곱의 잘린 자릿수 합계 계산


12

양의 정수 n이 출력되면 π n 의 소수 부분의 첫 n 자릿수 의 합이 출력 됩니다.

입력 및 출력 예 :

1 →
12 → 14
3 → 6
4 → 13
5 → 24
50 → 211500
→ 2305
5000 → 22852

π의 자릿수를 계산 하거나 거듭 제곱 또는 연속 분수를 평가하는 내장 함수 는 허용되지 않습니다. 표준 허점이 적용됩니다. 입 / 출력은 편리한 형식 (stdin, stdout, function in / output 등) 일 수 있습니다.

바이트 단위의 최단 코드가 이깁니다.


pi를 계산하는 데 사용될 수 있지만 arctangent 또는 허수 로그와 같이 직접적으로 필요한 것은 아닌 다른 trig 함수도 금지됩니까? 또한 실패 할 수있는 n에 대한 상한이 있습니까?
FryAmTheEggman

@FryAmTheEggman이 trig 함수가 임의의 pi 숫자를 계산할 수 있으면 금지됩니다. 프로그램은 이론적으로 n에 대해 작동해야 하지만 런타임 또는 메모리가 너무 높아지면 용서됩니다.
orlp

답변:


4

파이썬-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]))

입력은 stdin에서 가져옵니다. 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 nn 번째 대체 수 이며, 크기 n 세트의 교호 순열 수로 공식적으로 정의 할 수 있습니다 (또한 A000111 참조 ). 대안 적으로, 서열은 탄젠트 수 및 시컨트 수 ( A 2n = S n , A 2n + 1 = T n ) 의 조성으로 정의 될 수 있으며 , 이에 대해서는 추후에 더 설명한다.

작은 보정 계수 c nn 이 커짐에 따라 1 로 빠르게 수렴합니다 .

들어 N = 1 의 평가에이 양의 라이프니츠 시리즈 . π10 ½ 로 근사 하면 필요한 항의 수는 다음과 같이 계산할 수 있습니다.

n의 값이 작을수록 더 많은 값이 필요 하지만 17로 수렴 합니다.

A n 의 계산 에는 몇 가지 알고리즘과 명시 적 공식이 있지만 모두 n 으로 이차합니다 . 원래 Seidel 's Algorithm 의 구현을 코딩 했지만 실용하기에는 너무 느립니다. 각 반복마다 추가 항을 저장해야하며 항의 크기가 매우 빠르게 증가합니다 ( "잘못된"종류의 O (n 2 ) ).

첫 번째 스크립트는 원래 Knuth와 Buckholtz에서 제공 한 알고리즘의 구현을 사용합니다 .

모든 k = 1..n에 대해 T 1, k = 1 이라고합시다.

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 만큼 2 차적 이므로, ~ 4x 속도 개선입니다.


1
답 뒤에 숨겨진 수학에 대한 훌륭한 설명.
Logic Knight

3

파이썬 2, 246 바이트

나는 2 차 수렴으로 Calculate π 에서 내 대답에 비슷한 접근 방식을 취했습니다 . 마지막 줄은 pi의 N 제곱을 취하고 숫자를 합산합니다. N = 5000 테스트는 1 분 정도 걸립니다.

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

ungolfed 코드 :

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=jp=ja=p=jIIRC. 아마도.
Elias Benevedes

감사. 이 코드에는 더 많은 골프 최적화가 있지만 Decimal이없는 ​​알고리즘을 사용하여 다시 쓰지 않으면 경쟁이되지 않습니다.
Logic Knight

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 반복이 필요합니다.
primo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.