Twoim zadaniem jest stworzenie najwolniejszej rosnącej funkcji, która nie może przekraczać 100 bajtów.
Twój program weźmie jako dane wejściowe nieujemną liczbę całkowitą i wyświetli nieujemną liczbę całkowitą. Nazwijmy twój program P.
Musi spełniać te dwa kryteria:
- Kod źródłowy musi być mniejszy lub równy 100 bajtów.
- Dla każdego K istnieje N, takie, że dla każdego n> = N, P (n)> K. Innymi słowy, lim (n-> ∞) P (n) = ∞ . (To właśnie oznacza, że „rośnie”).
Twój „wynik” to tempo wzrostu funkcji podstawowej programu.
Mówiąc dokładniej, program P rośnie wolniej niż Q, jeśli istnieje taki N, że dla wszystkich n> = N, P (n) <= Q (n), i jest co najmniej jeden n> = N taki, że P (n ) <Q (n). Jeśli żaden program nie jest lepszy od drugiego, są one powiązane. (Zasadniczo, który program jest wolniejszy, zależy od wartości lim (n-> ∞) P (n) -Q (n).)
Zgodnie z definicją z poprzedniego akapitu najwolniejszą funkcją wzrostu jest ta, która rośnie wolniej niż jakakolwiek inna funkcja.
Jest to golf o tempie wzrostu, więc wygrywa najwolniej rozwijający się program!
Uwagi:
- Aby pomóc w punktacji, spróbuj podać w odpowiedzi funkcję obliczoną przez Twój program.
- Dodaj także (teoretyczne) dane wejściowe i wyjściowe, aby pomóc ludziom zorientować się, jak wolno możesz jechać.
źródło
<
po niej następuje litera jako początek znacznika HTML. Przejrzyj swoje pytania, zanim je opublikujesz: POdpowiedzi:
Haskell, 98 bajtów, wynik = f ε 0 −1 ( n )
Jak to działa
Oblicza to odwrotność bardzo szybko rosnącej funkcji związanej z robakiem Beklemisheva . Jego tempo wzrostu jest porównywalne z f ε 0 , gdzie f α jest szybko rosnącą hierarchią, a ε 0 jest pierwszą liczbą epsilon .
Aby to porównać z innymi odpowiedziami, zwróć uwagę na to
źródło
Brachylog , 100 bajtów
Wypróbuj online!
Prawdopodobnie nie jest to bliskie powolności innych fantazyjnych odpowiedzi, ale nie mogłem uwierzyć, że nikt nie próbował tego prostego i pięknego podejścia.
Po prostu obliczamy długość liczby wejściowej, następnie długość tego wyniku, a następnie długość tego innego wyniku ... łącznie 100 razy.
Rośnie to tak szybko, jak log (log (log ... log (x), przy 100 logach base-10).
Jeśli wpiszesz swój numer jako ciąg , będzie on działał niezwykle szybko na każdym wejściu, którego możesz spróbować, ale nie oczekuj, że kiedykolwiek zobaczysz wynik większy niż 1: D
źródło
JavaScript (ES6), funkcja odwrotna Ackermanna *, 97 bajtów
* jeśli zrobiłem to dobrze
Funkcja
A
jest funkcją Ackermanna . Funkcjaa
ma być funkcją odwrotnej Ackermanna . Jeśli poprawnie go zaimplementowałem, Wikipedia mówi, że nie trafi,5
dopóki nie będziem
równy2^2^2^2^16
. MamStackOverflow
wokół siebie1000
.Stosowanie:
Objaśnienia:
Funkcja Ackermanna
Odwrotna funkcja Ackermanna
źródło
Pure Evil: Eval
Instrukcja wewnątrz eval tworzy ciąg o długości 7 * 10 10 10 10 10 10 8.57, który składa się wyłącznie z wywołań funkcji lambda, z których każde będzie konstruować ciąg o podobnej długości, tak długo, aż w końcu stanie
y
się 0. Pozornie ma to tę samą złożoność co poniższa metoda Eschew, ale zamiast polegać na logice „i-lub-lub”, po prostu rozbija gigantyczne łańcuchy razem (a wynik netto jest coraz większy stosów ... prawdopodobnie?).Największą
y
wartością, jaką mogę podać i obliczyć bez zgłaszania błędu przez Python, jest 2, co jest już wystarczające do zmniejszenia wartości wejściowej max-float do zwracania 1.Łańcuch o długości 7,625,597,484,987 jest po prostu zbyt duży:
OverflowError: cannot fit 'long' into an index-sized integer
.Powinienem przestać
Unikaj
Math.log
: Przechodząc do (dziesiątego) źródła (problemu), Wynik: funkcja skutecznie nie do odróżnienia od y = 1.Importowanie biblioteki matematycznej ogranicza liczbę bajtów. Pozbądźmy się tego i zastąpmy
log(x)
funkcję czymś w przybliżeniu równoważnym:x**.1
i która kosztuje w przybliżeniu taką samą liczbę znaków, ale nie wymaga importu. Obie funkcje mają podliniowe wyjście względem wejścia, ale x 0,1 rośnie jeszcze wolniej . Jednak nie obchodzi nas to zbytnio, dbamy tylko o to, że ma ten sam podstawowy wzorzec wzrostu w odniesieniu do dużych liczb, zużywając porównywalną liczbę znaków (np.x**.9
Jest taka sama liczba znaków, ale rośnie szybciej, więc jest to pewna wartość, która wykazałaby dokładnie taki sam wzrost).Teraz, co zrobić z 16 postaciami. Co powiesz na ... rozszerzenie naszej funkcji lambda o właściwości Sekwencji Ackermanna? Ta odpowiedź dla dużej liczby zainspirowała to rozwiązanie.
z**z
Część tutaj powstrzymuje mnie przed uruchomieniem tej funkcji w dowolnym miejscu blisko do rozsądnych wejść doy
iz
największe wartości mogę wykorzystać to 9 i 3 , dla którego wrócę wartość 1,0, nawet dla największych podpór pływak Pythona (Uwaga: podczas 1,0 jest liczbowo większy niż 6.77538853089e-05, zwiększone poziomy rekurencji zbliżają wyjście tej funkcji do 1, pozostając większe niż 1, podczas gdy poprzednia funkcja przenosiła wartości bliższe 0, pozostając większa niż 0, w ten sposób nawet umiarkowaną rekurencję dla tej funkcji powoduje tyle operacji, że liczba zmiennoprzecinkowa traci wszystkie znaczące bity).Ponowna konfiguracja oryginalnego wywołania lambda w celu uzyskania wartości rekurencji 0 i 2 ...
Jeśli zostanie wykonane porównanie z „przesunięciem od 0” zamiast „przesunięciem z 1”, funkcja ta zwraca wartość
7.1e-9
, która jest zdecydowanie mniejsza niż6.7e-05
.Rzeczywista podstawowa rekurencja programu (wartość z) wynosi 10 10 10 10 1,97 poziomów głębokości, gdy tylko y się wyczerpie, resetuje się z 10 10 10 10 10 1,97 (dlatego wystarcza wartość początkowa 9), więc nie nawet nie wiem, jak poprawnie obliczyć całkowitą liczbę rekurencji: doszedłem do końca mojej wiedzy matematycznej. Podobnie nie wiem, czy przeniesienie jednego z
**n
wykładników z początkowego sygnału wejściowego na wtórnyz**z
poprawiłoby liczbę rekurencji, czy też nie (podobnie jak odwrotnie).Idziemy jeszcze wolniej z jeszcze większą rekurencją
n//1
- oszczędza 2 bajtyint(n)
import math
,math.
oszczędza 1 bajtfrom math import*
a(...)
oszczędza łącznie 8 bajtówm(m,...)
(y>0)*x
zapisuje bajt overy>0and x
9**9**99
zwiększa liczbę bajtów o 4 i zwiększa głębokość rekurencji o około2.8 * 10^x
gdziex
jest stara głębokość (lub głębokość zbliżona do googolplex w rozmiarze: 10 10 94 ).9**9**9e9
zwiększa liczbę bajtów o 5 i zwiększa głębokość rekurencji o ... szaloną ilość. Głębokość rekurencji wynosi teraz 10 10 10 9,93 , dla porównania, googolplex wynosi 10 10 10 2 .m(m(...))
doa(a(a(...)))
kosztów 7 bajtówNowa wartość wyjściowa (przy 9 głębokości rekurencji):
Głębokość rekurencji eksplodowała do punktu, w którym ten wynik jest dosłownie bez znaczenia, z wyjątkiem porównania z wcześniejszymi wynikami używającymi tych samych wartości wejściowych:
log
25 razyLambda Incepcja, wynik: ???
Słyszałem, że lubisz lambdas, więc ...
Nie mogę nawet tego uruchomić, układam przepełnienie nawet przy zaledwie 99 warstwach rekurencji.
Stara metoda (poniżej) zwraca (pomijając konwersję do liczby całkowitej):
Nowa metoda powraca, używając tylko 9 warstw wtargnięcia (zamiast ich pełnego googola ):
Myślę, że to działa podobnie do sekwencji Ackermana, tylko małe zamiast duże.
Również dzięki produktom ETH za 3-bajtowe oszczędności w przestrzeniach, o których nie wiedziałem, że można je usunąć.
Stara odpowiedź:
Skrócenie liczb całkowitych dziennika funkcji (i + 1) iterowało
2025 razy (Python) przy użyciu lambda'd lambda.Odpowiedź PyRuleza można skompresować, wprowadzając drugą lambdę i układając ją w stos:
99100 używanych znaków.Powoduje to iterację
2025, w stosunku do oryginału 12. Dodatkowo zapisuje 2 znaki, używającint()
zamiast tegofloor()
dozwolonego dla dodatkowegox()
stosu.Jeśli spacje po lambda można usunąć (nie mogę w tej chwili sprawdzić),Możliwy!y()
można dodać piątą .Jeśli istnieje sposób na pominięcie
from math
importu przy użyciu w pełni kwalifikowanej nazwy (np.x=lambda i: math.log(i+1))
), To zaoszczędziłoby jeszcze więcej znaków i pozwoliłoby na inny stos,x()
ale nie wiem, czy Python obsługuje takie rzeczy (podejrzewam, że nie). Gotowy!Jest to w zasadzie ta sama sztuczka, którą zastosowano w blogu XCKD na dużą liczbę , jednak narzut związany z deklarowaniem lambdas wyklucza trzeci stos:
Jest to najmniejsza możliwa rekurencja z 3 lambdami, która przekracza obliczoną wysokość stosu 2 lambdas (zmniejszenie dowolnej lambdy do dwóch wywołań obniża wysokość stosu do 18, poniżej wysokości wersji 2-lambda), ale niestety wymaga 110 znaków.
źródło
int
konwersji i myślałem, że mam części zamienne.import
i spację poy<0
. Nie znam jednak dużo Pythona, więc nie jestem pewieny<0and x or m(m,m(m,log(x+1),y-1),y-1)
zapisać kolejny bajt (zakładając, żex
nie ma0
kiedyy<0
)log(x)
rośnie wolniej niż DOWOLNA moc dodatniax
(dla dużych wartościx
), i nie jest to trudne do wykazania przy użyciu reguły L'Hopital. Jestem prawie pewien, że twoja obecna wersja robi(...(((x**.1)**.1)**.1)** ...)
wiele razy. Ale te moce po prostu się mnożą, więc jest to efektywnex**(.1** (whole bunch))
, co jest (bardzo małą) siłą pozytywnąx
. Oznacza to, że faktycznie rośnie szybciej niż JEDNA iteracja funkcji dziennika (chociaż, oczywiście, musiałbyś spojrzeć na BARDZO duże wartościx
zanim zauważysz ... ale to właśnie rozumiemy przez „przejście w nieskończoność” ).Haskell , 100 bajtów
Wypróbuj online!
To rozwiązanie nie przyjmuje odwrotności szybko rosnącej funkcji, zamiast tego przyjmuje raczej wolno rosnącą funkcję, w tym przypadku
length.show
, i stosuje ją kilka razy.Najpierw definiujemy funkcję
f
.f
to drań wersja notacji Knutha, która rośnie nieco szybciej (nieco to trochę mało powiedziane, ale liczby, z którymi mamy do czynienia, są tak duże, że w wielkim schemacie rzeczy ...). Definiujemy podstawowy przypadekf 0 a b
by byća^b
luba
do potęgib
. Następnie definiujemy ogólny przypadek do(f$c-1)
zastosowania wb+2
wystąpieniacha
. Gdybyśmy zdefiniowali konstrukt typu Knut w górę, zastosowalibyśmy go dob
przypadkówa
, aleb+2
jest bardziej golfistą i ma tę zaletę, że szybciej rośnie.Następnie definiujemy operatora
#
.a#b
jest zdefiniowane jakolength.show
stosowane dob
a
czasów. Każde zastosowanielength.show
jest w przybliżeniu równe log 10 , co nie jest bardzo szybko rosnącą funkcją.Następnie zaczynamy definiować naszą funkcję,
g
która przyjmuje i przyjmuje liczbę całkowitą i stosujelength.show
się do liczby całkowitej kilka razy. Mówiąc konkretniej, dotyczylength.show
to danych wejściowychf(f 9 9 9)9 9
. Zanim przejdziemy do tego, jak duże to jest, spójrzmyf 9 9 9
.f 9 9 9
jest większy niż9↑↑↑↑↑↑↑↑↑9
(dziewięć strzał) o ogromny margines. Uważam, że jest to gdzieś pomiędzy9↑↑↑↑↑↑↑↑↑9
(dziewięć strzał) a9↑↑↑↑↑↑↑↑↑↑9
(dziesięć strzał). Teraz jest to niewyobrażalnie duża liczba, zbyt duża, aby przechowywać ją na dowolnym istniejącym komputerze (w zapisie binarnym). Następnie bierzemy to i stawiamy jako nasz pierwszy argument,f
który oznacza, że nasza wartość jest większa niż9↑↑↑↑↑↑...↑↑↑↑↑↑9
zf 9 9 9
strzały pomiędzy. Nie zamierzam opisywać tej liczby, ponieważ jest ona tak duża, że nie sądzę, że byłbym w stanie to zrobić sprawiedliwie.Każda
length.show
jest w przybliżeniu równa przyjęciu podstawy logarytmu 10 liczby całkowitej. Oznacza to, że większość liczb zwróci 1, gdyf
zostanie do nich zastosowana. Najmniejsza liczba do zwrócenia czegoś innego niż 110↑↑(f(f 9 9 9)9 9)
, która zwraca 2. Zastanówmy się przez chwilę. Jakkolwiek okropnie duża, jak liczba, którą zdefiniowaliśmy wcześniej, najmniejsza liczba, która zwraca 2, wynosi tyle razy, ile wynosi 10. To 1, po których następuje10↑(f(f 9 9 9)9 9)
zero.W ogólnym przypadku
n
najmniejszego wyjścia na wyjściu musi być dowolne n(10↑(n-1))↑↑(f(f 9 9 9)9 9)
.Zauważ, że ten program wymaga ogromnej ilości czasu i pamięci nawet dla małych n (więcej niż we wszechświecie wiele razy), jeśli chcesz to przetestować, sugeruję zastąpienie
f(f 9 9 9)9 9
go znacznie mniejszą liczbą, spróbuj 1 lub 2, jeśli chcesz kiedykolwiek uzyskasz wynik inny niż 1.źródło
APL, Zastosuj
log(n + 1)
,e^9^9...^9
czasy, gdzie długość łańcucha jest równae^9^9...^9
długości łańcucha minus 1 razy i tak dalej.źródło
e^n^n...^n
części, więc zmieniłem ją w stałą, ale to może być prawdaMATL , 42 bajty
Wypróbuj online!
Program ten oparty jest na szeregach harmonicznych z wykorzystaniem stałej Eulera – Mascheroniego. Kiedy czytałem dokumentację @LuisMendo na temat jego języka MATL (dużymi literami, więc wygląda to na ważne) zauważyłem tę stałą. Wyrażenie funkcji powolnego wzrostu jest następujące:
gdzie εk ~ 1 / 2k
Testowałem do 10000 iteracji (w Matlabie, ponieważ jest on zbyt duży dla TIO) i ma wynik poniżej 10, więc jest bardzo wolny.
Objaśnienia:
Dowód empiryczny: (ln k ) + 1 na czerwono zawsze powyżej ln k + γ + εk na niebiesko.
Program dla (ln k ) + 1 został utworzony w
Matlab,
471814 bajtówCiekawe, że minął czas dla n = 100 to 0,208693s na moim laptopie, ale tylko 0,121945s z,
d=rand(1,n);A=d*0;
a nawet mniej, 0,12147s zA=zeros(1,n)
. Jeśli zera to marnowanie miejsca, oszczędza prędkość! Ale odbiegam od tematu (prawdopodobnie bardzo powoli).Edycja: dzięki Stewie za
pomoc wzmniejszeniu tego wyrażenia Matlab do:źródło
n=input('');A=log(1:n)+1
albo jako bezimiennego funkcji anonimowej (14 bajtów)@(n)log(1:n)+1
. Nie jestem pewien co do MATLAB, aleA=log(1:input(''))+1
pracuje w Octave ...n=input('');A=log(1:n)+1
działa,@(n)log(1:n)+1
nie rób tego (naprawdę poprawna funkcja z uchwytem w Matlabie, ale nie pytamy o dane wejściowe),A=log(1:input(''))+1
działa i można ją skrócićlog(1:input(''))+1
f=
nie muszą być policzone, ponieważ jest to możliwe tylko do:@(n)log(1:n)+1
a następnieans(10)
, aby uzyskać pierwsze 10 cyfr.Python 3 , 100 bajtów
Dół dziennika funkcji (i + 1) iterował 99999999999999999999999999999999999 razy.
Można użyć wykładników, aby powyższa liczba była jeszcze większa ...
Wypróbuj online!
źródło
9**9**9**...**9**9e9
?Dół dziennika funkcji (i + 1) iterował 14 razy (Python)
Nie spodziewam się, że będzie to bardzo dobre, ale pomyślałem, że to dobry początek.
Przykłady:
źródło
int
zamiastfloor
, możesz zmieścić innyx(
e^e^e^e...^n
? Ponadto, dlaczego po znaku jest spacja:
?x()
połączenie?Rubin, 100 bajtów, wynik -1 = f ω ω + 1 (n 2 )
Zasadniczo zapożyczony z mojego największego numeru do druku , oto mój program:
Wypróbuj online
Zasadniczo oblicza odwrotność f ω ω + 1 (n 2 ) w szybko rosnącej hierarchii. Pierwsze kilka wartości to
A potem kontynuuje produkcję
2
przez bardzo długi czas. Nawetx[G] = 2
, gdzieG
jest liczba Grahama.źródło
Mathematica, 99 bajtów
(przy założeniu, że ± zajmuje 1 bajt)
Pierwsze 3 polecenia definiują
x±y
do ocenyAckermann(y, x)
.Wynikiem tej funkcji jest to, ile razy
f(#)=#±#±#±#±#±#±#±#
należy zastosować 1, zanim wartość osiągnie wartość parametru. Ponieważf(#)=#±#±#±#±#±#±#±#
(czylif(#)=Ackermann[Ackermann[Ackermann[Ackermann[Ackermann[Ackermann[Ackermann[#, #], #], #], #], #], #], #]
) rośnie bardzo szybko, funkcja rośnie bardzo wolno.źródło
Clojure, 91 bajtów
Rodzaj oblicza
sum 1/(n * log(n) * log(log(n)) * ...)
, który znalazłem stąd . Ale funkcja skończyła się na 101 bajtach, więc musiałem usunąć jawną liczbę iteracji, a zamiast tego iterować, dopóki liczba jest większa niż jeden. Przykładowe dane wyjściowe dla danych wejściowych10^i
:Zakładam, że ta zmodyfikowana seria wciąż się różni, ale teraz wiem, jak to udowodnić.
źródło
JavaScript (ES6), 94 bajty
Objaśnienie :
Id
odnosi sięx => x
poniżej.Najpierw spójrzmy na:
p(Math.log)
jest w przybliżeniu równylog*(x)
.p(p(Math.log))
jest w przybliżeniu równalog**(x)
(ile razy możesz wziąć,log*
aż wartość wyniesie najwyżej 1).p(p(p(Math.log)))
jest w przybliżeniu równylog***(x)
.Odwrotna funkcja Ackermanna
alpha(x)
jest w przybliżeniu równa minimalnej liczbie powtórzeń, które trzeba skomponować,p
aż wartość wyniesie co najwyżej 1.Jeśli następnie użyjemy:
wtedy możemy pisać
alpha = p(Id)(Math.log)
.To dość nudne, więc zwiększmy liczbę poziomów:
To jest tak, jak skonstruowaliśmy
alpha(x)
, tylelog**...**(x)
że teraz robimyalpha**...**(x)
.Po co tu jednak zatrzymywać się?
Jeśli poprzednia funkcja jest
f(x)~alpha**...**(x)
, ta jest teraz~ f**...**(x)
. Robimy jeszcze jeden poziom, aby uzyskać nasze ostateczne rozwiązanie.źródło
p(p(x => x - 2))
jest w przybliżeniu równelog**(x)
(ile razy możesz wziąć,log*
aż wartość wyniesie najwyżej 1)”. Nie rozumiem tego stwierdzenia. Wydaje mi się, żep(x => x - 2)
powinno to być „tyle razy, ile możesz odjąć,2
aż wartość wyniesie co najwyżej 1”. Oznacza to, że p (x => x - 2) `powinno być funkcją„ dziel przez 2 ”. Dlategop(p(x => x - 2))
powinna być „liczba razy, którą można podzielić przez 2, dopóki wartość nie będzie co najwyżej 1” ... to znaczy, powinna to byćlog
funkcja, nielog*
lublog**
. Być może można to wyjaśnić?p = f => x => x < 2 ? 0 : 1 + p(p(f))(f(x))
tam, gdziep
jest przekazywanap(f)
jak w innych liniach, a nief
.