Pi razy e (lub Pie, jeśli lubisz niejednoznaczny zapis) do 100 miejsc po przecinku, wynosi:
8.5397342226735670654635508695465744950348885357651149618796011301792286111573308075725638697104739439...
( OIES A019609 ) ( argument za możliwą nieracjonalnością )
Twoim zadaniem jest napisanie programu, który przyjmuje dodatnią liczbę całkowitą N i wyprowadza Pi * e obcięte do N miejsc dziesiętnych. np. jeśli N = 2, to wynik powinien wynosić 8.53
.
Jest to problem związany z optymalizacją, więc wygrana zostanie przesłana, która może dać poprawny wynik dla najwyższej wartości N.
Aby upewnić się, że wszystkie zgłoszenia są oceniane przy użyciu tej samej mocy obliczeniowej, kod musi być uruchamiany na ideone , w dowolnym obsługiwanym języku. Zgodnie z ideone faq , dla niezalogowanych użytkowników istnieje 5 sekundowy limit czasu działania. Tego 5-sekundowego limitu należy użyć, a nie 15-sekundowego limitu dla zalogowanych użytkowników. (Zobacz często zadawane pytania na temat innych ograniczeń, takich jak pamięć, rozmiar kodu itp.)
W szczególności każdy, kto nie jest zalogowany do ideone, powinien mieć możliwość uruchomienia programu na ideone dla wszystkich wartości N od 1 do pewnego maksymalnego momentu obrotowego Nmax i widzieć prawidłowe wyjście prawie przez cały czas . bez Time limit exceeded
lub Memory limit exceeded
itp błędy. Zgłoszenie z największym Nmax wygrywa.
(To, czy faktyczny czas zajmuje smidge w ciągu 5 sekund, nie ma znaczenia, dopóki ideone nie powoduje błędów. „ Prawie cały czas ” jest definiowany jako ponad 95% czasu dla dowolnego konkretnego N.)
Detale
- Możesz użyć dowolnej metody matematycznej, którą chcesz obliczyć Pi * e, ale nie możesz zakodować wyjścia poza pierwszymi tuzinami cyfr Pi, e lub Pi * e .
- Twój program powinien być w stanie pracować dla dowolnego N, biorąc pod uwagę nieograniczone zasoby.
- Możesz użyć wbudowanych stałych Pi lub e, jeśli Twój język je posiada.
- Nie możesz uzyskiwać dostępu do stron internetowych ani zasobów zewnętrznych w stosunku do twojego kodu (jeśli ideone na to zezwala).
- Oprócz stałego kodowania i dostępu do zasobów zewnętrznych wszystko, co pozwala ideone, jest prawie na pewno w porządku.
- Twoje dane wejściowe i wyjściowe muszą (oczywiście) współpracować z tym, co ideone zapewnia we / wy (wydaje się, że tylko stdin / stdout). W porządku, jeśli potrzebujesz cudzysłowów wokół wejścia N lub jeśli dane wyjściowe są podobne
ans = ...
, itp. - Podaj link do fragmentu ideonu kodu wraz z danymi wejściowymi Nmax.
- Jeśli zdarzy się remis (możliwe tylko, jeśli wiele zgłoszeń osiągnie limit znaków wyjściowych 64kB), odpowiedź najwyższych głosów wygrywa.
źródło
Odpowiedzi:
Python - 65535
http://ideone.com/knKRhn
Wygląda na to, że Ideone nie został
gmpy2
zainstalowany, co jest niefortunne z co najmniej dwóch powodów. Po pierwsze, ponieważ spowodowałoby to znacznie szybsze obliczanie, a po drugie, ponieważ sprawia, że każda formuła wymagająca arbitralnej precyzji pierwiastka kwadratowego jest niepraktyczna.Wzór, którego używam dla π, został wymieniony przez Ramanujana jako Wzór (39):
co zbiega się w tempie ~ 5,89 cyfr na termin. Według mojej wiedzy jest to najszybsza zbieżna seria tego rodzaju, która nie wymaga oceny pierwiastka kwadratowego o dowolnej precyzji. Wzór (44) w tym samym papierze (szybkość zbieżności ~ 7.98 cyfr na słowa) jest często nazywany w Ramanujana wzorze.
Wzór, którego używam dla e, jest sumą odwrotnych silni. Liczba wymaganych terminów jest obliczana jako Γ -1 ( 10 n ), przy użyciu przybliżenia, które znalazłem na matematycznym przepływie . Składnik Lambert W 0 można znaleźć przy użyciu metody Newtona.
Obliczenia każdego z tych podsumowań dokonuje się za pomocą Szybkiej oceny funkcji E (bardziej ogólnie nazywanej dzieleniem binarnym), pierwotnie opracowanej przez Karatsubę. Metoda redukuje sumowanie do n warunków do pojedynczej wartości wymiernej p / q . Te dwie wartości są następnie mnożone, aby uzyskać końcowy wynik.
Aktualizacja:
Profilowanie ujawniło, że ponad połowa czasu potrzebnego na obliczenia została poświęcona na ostateczny podział. Aby uzyskać pełną precyzję, potrzebne są tylko najwyższe z logów 2 (10 n ) bitów q , więc najpierw odcinam kilka. Kod wypełnia teraz bufor wyjściowy Ideone w 3,33 s .
Aktualizacja 2:
Ponieważ jest to wyzwanie związane z optymalizacją , postanowiłem napisać własną procedurę podziału, aby zwalczyć powolność CPython. Realizacja
divnr
powyższa wykorzystuje Newton-Raphson Division . Ogólną ideą jest obliczenie d = 1 / q · 2 n przy użyciu metody Newtona, gdzie n jest liczbą bitów wymaganą przez wynik, i obliczenie wyniku jako p · d >> n . Czas działania wynosi teraz 2,87 s - i to nawet bez odcinania bitów przed obliczeniami; nie jest to konieczne w przypadku tej metody.źródło
PARI / GP: 33000
Jest to zasadniczo program podany w OEIS , zmodyfikowany w celu poprawnego pobierania i formatowania danych wyjściowych. Powinien służyć jako podstawa do pokonania, jeśli nic więcej.
Zakładam , że to jest poprawne. Sprawdziłem to przy 100 i 20k względem OEIS i pasowało do obu. Trudno jest znaleźć dalsze cyfry online, aby sprawdzić.
Dla 33 000 zajmuje to około 4,5 s, więc prawdopodobnie może być trochę zderzony. Właśnie zmęczyło mnie majstrowanie przy wejściu i powolnej pętli submission / compile / run ideone.
Link Ideone.com
źródło
Str(floor(frac(x)*10^m)
, idzie setki / tysiące razy szybciej.Python 3
Ponieważ wbudowane pi i e nie mają wystarczającej liczby cyfr, postanowiłem obliczyć własne.
Link IDEOne
Dane wyjściowe dla STDIN = 1000:
źródło
should be able to work for any N, given unlimited resources
reguły. Większość danych wyjściowych to zera w okolicach N = 10000.)NameError: name 'xrange' not defined
.Scala - 1790
IDEOne o http://ideone.com/A2CIto .
Używamy formuły Wetherfielda dla π (i kod formuły Machina z grubsza przeniesiony stąd ). Obliczamy e za pomocą zwykłej serii mocy.
źródło