Pozytywny całkowitą n i numer A , tym n -tego tetracja z jest zdefiniowany jako ^ ( ^ ( ^ (... ^ ))), w którym ^ oznacza potęgowanie (lub mocy), a ekspresja zawiera liczba dokładnie n razy.
Innymi słowy, tetracja jest iteracją potęgową iteracyjną. Dla n = 4 i a = 1,6 tetracja wynosi 1,6 ^ (1,6 ^ (1,6 ^ 1,6)) ≈ 3,5743.
Odwrotną funkcją tetracji w stosunku do n jest superlogarytm . W poprzednim przykładzie 4 jest super-logarytmem 3,5743 z „super-bazą” 1.6.
Wyzwanie
Biorąc pod uwagę dodatnią liczbę całkowitą n , znajdź x tak, że n jest super-logarytmem samego siebie w super-podstawie x . Oznacza to, że znajdź x taki, że x ^ ( x ^ ( x ^ (... ^ x )))) ( x pojawia się n razy) równa się n .
Zasady
Program lub funkcja dozwolona.
Formaty wejściowe i wyjściowe są jak zwykle elastyczne.
Algorytm powinien teoretycznie działać dla wszystkich liczb całkowitych dodatnich. W praktyce dane wejściowe mogą być ograniczone do wartości maksymalnej z powodu ograniczeń pamięci, czasu lub typu danych. Kod musi jednak działać dla danych wejściowych trwających 100
co najmniej krócej niż minutę.
Algorytm powinien teoretycznie dać wynik z 0.001
precyzją. W praktyce dokładność wyjściowa może być gorsza z powodu skumulowanych błędów w obliczeniach numerycznych. Jednak dane wyjściowe muszą być dokładne do 0.001
wskazanych przypadków testowych.
Najkrótszy kod wygrywa.
Przypadki testowe
1 -> 1
3 -> 1.635078
6 -> 1.568644
10 -> 1.508498
25 -> 1.458582
50 -> 1.448504
100 -> 1.445673
Realizacja referencyjna
Oto implementacja referencyjna w Matlab / Octave (wypróbuj w Ideone ).
N = 10; % input
t = .0001:.0001:2; % range of possible values: [.0001 .0002 ... 2]
r = t;
for k = 2:N
r = t.^r; % repeated exponentiation, element-wise
end
[~, ind] = min(abs(r-N)); % index of entry of r that is closest to N
result = t(ind);
disp(result)
Do N = 10
tego daje result = 1.5085
.
Poniższy kod jest sprawdzeniem dokładności wyjściowej przy użyciu arytmetyki o zmiennej precyzji:
N = 10;
x = 1.5085; % result to be tested for that N. Add or subtract 1e-3 to see that
% the obtained y is farther from N
s = num2str(x); % string representation
se = s;
for n = 2:N;
se = [s '^(' se ')']; % build string that evaluates to iterated exponentiation
end
y = vpa(se, 1000) % evaluate with variable-precision arithmetic
To daje:
- Dla
x = 1.5085
:y = 10.00173...
- Dla
x = 1.5085 + .001
:y = 10.9075
- Bo
x = 1.5085 - .001
dajey = 9.23248
.
więc 1.5085
jest prawidłowym rozwiązaniem z .001
precyzją.
x
zbiegają się jakn
podejść nieskończoność?Odpowiedzi:
Dyalog APL ,
3325 bajtówPotrzeby,
⎕IO←0
które są domyślne w wielu systemach.Teoretycznie oblicza się dla wszystkich liczb całkowitych, ale praktycznie ogranicza się tylko do bardzo małych.
Wypróbuj APL online!
źródło
Haskell,
555452 bajtówStosowanie:
Dzięki @nimi za 1 bajt!
Dzięki @xnor za 2!
źródło
[ ]!!0
zamiasthead[ ]
zapisuje bajts n=[x|x<-[2,1.9999..],n>iterate(x**)1!!n]!!0
byłoby krótsze, gdybyś mógł skłonić Haskell do zaakceptowania jego typów.JavaScript, ES6: 77 bajtów / ES7:
5753 bajtówES6
ES7
Używanie
**
zgodnie z sugestią DanTheMan:Przykład
źródło
**
zamiastMath.pow
.Mathematica,
4033 bajtówDzięki murphy za prawie 20% oszczędności!
Nest[x^#&,1,n]
daje n-te tetrację x. Testuje więcNest[x^#&,1,#]<#
, czy tetracja (wejściowa) x jest mniejsza niż (wejściowa). Po prostu zaczynamy od x = 1 i dodajemy 0,001 wielokrotnie, aż tetracja jest zbyt duża, a następnie wypisujemy ostatnią wartość x (więc odpowiedź jest gwarantowana, że jest większa niż dokładna wartość, ale w granicach 0,001).Ponieważ powoli się uczę:
//.x_:>y/;z
lub//.x_/;z:>y
oznacza „szukaj wszystkiego, co pasuje do szablonu x, ale tylko rzeczy, dla których test z zwraca wartość true, a następnie działaj na x według reguły y; wielokrotnie, aż nic się nie zmieni”. Tutaj szablonx_
jest po prostu „dowolną liczbą, którą widzę”, chociaż w innych kontekstach można go jeszcze bardziej ograniczyć.Gdy wartość wejściowa wynosi co najmniej 45, tetracja rośnie tak szybko, że ostatni krok powoduje błąd przepełnienia; ale wartość x jest wciąż aktualizowana i wysyłana poprawnie. Zmniejszenie wielkości kroku z 0,001 do 0,0001 rozwiązuje ten problem dla danych wejściowych do 112 i daje bardziej precyzyjną odpowiedź na rozruch (i nadal działa szybko, za około kwadrans). Ale to jeden dodatkowy bajt, więc zapomnij o tym!
Orginalna wersja:
źródło
1//.x_:>x+.001/;Nest[x^#&,1,#]<#&
//.
bez pomocy :)J,
393128 bajtówNa podstawie implementacji referencyjnej. Jest dokładny z dokładnością do trzech miejsc po przecinku.
Zapisano 8 bajtów przy użyciu metody z rozwiązania @ Adám .
Stosowanie
Dodatkowe polecenia używane do formatowania wielu wejść / wyjść.
Wyjaśnienie
źródło
Python, 184 bajty
Wyjście testowe (pomijanie rzeczywistych instrukcji drukowania):
źródło
s(1000000)
dość szybkoRakieta 187 bajtów
Testowanie:
Wynik:
Wersja szczegółowa:
źródło
Perl 6 , 42 bajtów
(Tłumaczenie przykładowego kodu Matlab)
Test:
źródło
PHP, 103 bajtów
źródło
Axiom 587 bajtów
mniej golfa + liczby
źródło
Common Lisp, 207 bajtów
Używanie
reduce
z:from-end t
unika potrzeby wykonywania „odwrotnego potęgowania” pośredniej lambda (w zasadzie(lambda (x y) (expt y x))
oszczędzając 14 bajtów (12, jeśli usuniesz usuwalne spacje).Nadal musimy obsłużyć przepełnienie zmiennoprzecinkowe, ale
ignore-errors
formularz zwraca się,nil
jeśli wystąpił błąd, więc możemy użyćor
wartości domyślnej.źródło