Obliczanie obciętych cyfr sumy potęg pi


12

Biorąc pod uwagę dodatnią liczbę całkowitą n wyjściową, suma pierwszych n cyfr dziesiętnych części ułamkowej π n .

Przykładowe dane wejściowe i wyjściowe:

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

Wbudowane funkcje obliczające cyfry π lub oceniające albo szeregi mocy, albo ciągłe ułamki są niedozwolone. Obowiązują standardowe luki . Wejścia / wyjścia mogą mieć wygodny format (stdin, stdout, funkcja wejścia / wyjścia itp.).

Najkrótszy kod w bajtach wygrywa.


Czy inne funkcje wyzwalające, które mogą być użyte do obliczenia liczby pi, ale niekoniecznie bezpośrednio, jak np. Arcus tangens lub wyimaginowane logarytmy, są również zakazane? Czy jest też górna granica n, po której może się nie powieść?
FryAmTheEggman

@FryAmTheEggman Jeśli te funkcje wyzwalające mogą obliczyć dowolne cyfry pi, to tak, są one zbanowane. Twój program powinien działać teoretycznie dla dowolnego n , ale jest to wybaczane, jeśli środowisko wykonawcze lub pamięć stają się zbyt wysokie.
orlp

Odpowiedzi:


4

Python - 191 bajtów

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

~ 4x szybsza wersja - 206 bajtów

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

Dane wejściowe są pobierane ze standardowego wejścia. Wyjście dla n = 5000 zajmuje około 14s przy drugim skrypcie (lub 60s przy pierwszym).


Przykładowe użycie:

$ 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

Zastosowana formuła jest następująca:

gdzie A n jest n- liczbą naprzemienną , którą można formalnie zdefiniować jako liczbę naprzemiennych permutacji w zbiorze wielkości n (patrz także: A000111 ). Alternatywnie sekwencja może być zdefiniowana jako kompozycja o numerach styczna siecznej liczb ( 2n = S n , 2n + 1 = T n ), o tym później.

Mały współczynnik korygujący c n szybko zbliża się do 1, gdy n staje się duży i jest określony przez:

Dla n = 1 oznacza to ocenę serii Leibniza . Zbliżenie π jako 10 pół liczba wymaganych warunków może być obliczona jako:

co zbiega się (w zaokrągleniu w górę) do 17 , chociaż mniejsze wartości n wymagają znacznie więcej.

Do obliczenia A n istnieje kilka algorytmów, a nawet wyraźna formuła, ale wszystkie są kwadratowe według n . Pierwotnie kodowałem implementację algorytmu Seidela , ale okazuje się on zbyt wolny, aby był praktyczny. Każda iteracja wymaga zapisania dodatkowego terminu, a jego terminy bardzo szybko rosną („zły” rodzaj O (n 2 ) ).

Pierwszy skrypt wykorzystuje implementację algorytmu pierwotnie podanego przez Knutha i Buckholtza :

Niech T 1, k = 1 dla wszystkich k = 1..n

Kolejne wartości T są podane przez relację powtarzalności:

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

N jest wstrzykiwany przez T n, 1

(patrz także: A185414 )

Chociaż nie jest to wyraźnie określone, algorytm oblicza jednocześnie zarówno Liczby Styczne, jak i Liczby Secant. Drugi skrypt wykorzystuje odmianę tego algorytmu autorstwa Brenta i Zimmermanna , która oblicza T lub S , w zależności od parzystości n . Poprawa jest kwadratowa o n / 2 , stąd poprawa prędkości ~ 4x.


1
Doskonałe wyjaśnienie matematyki stojącej za twoją odpowiedzią.
Logic Knight

3

Python 2, 246 bajtów

Podjąłem podobne podejście do mojej odpowiedzi w Calculate π z kwadratową zbieżnością . Ostatnia linia przyjmuje N-tą potęgę pi i sumuje cyfry. Test N = 5000 zajmuje około minuty.

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

Niektóre testy:

$ 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

Nieskluczony kod:

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

Linia 8, można włączyć a=ji p=jdo a=p=jIIRC. Może.
Elias Benevedes

Dzięki. Istnieje więcej optymalizacji gry w golfa dla tego kodu, ale nie będzie on konkurencyjny bez przepisywania przy użyciu algorytmu bez dziesiętnego.
Logic Knight

1

Pyth, 33

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

Na podstawie tej odpowiedzi Isaacg . Prawdopodobnie można by grać w golfa więcej. Powolny.

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
Ta odpowiedź naprawdę wymaga co najmniej wystarczającego wyjaśnienia, aby uzasadnić, że oblicza wystarczającą liczbę cyfr, aby uzyskać właściwą odpowiedź.
Peter Taylor

@PeterTaylor Jutro dodam wyjaśnienie, po prostu idę spać.
orlp

Każda iteracja daje jeden poprawny bit (patrz Załącznik A ). 2n cyfry powinny wymagać ~ 6,64n iteracji.
primo
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.