Ihre Aufgabe ist es, die am langsamsten wachsende Funktion in nicht mehr als 100 Bytes zu erstellen.
Ihr Programm nimmt eine nicht negative Ganzzahl als Eingabe und gibt eine nicht negative Ganzzahl aus. Nennen wir Ihr Programm P.
Es muss die beiden folgenden Kriterien erfüllen:
- Sein Quellcode muss kleiner oder gleich 100 Bytes sein.
- Für jedes K gibt es ein N, so dass für jedes n> = N, P (n)> K. Mit anderen Worten, lim (n-> ∞) P (n) = ∞ . (Dies ist, was es bedeutet, dass es "wächst".)
Ihre "Punktzahl" ist die Wachstumsrate der zugrunde liegenden Funktion Ihres Programms.
Insbesondere wächst das Programm P langsamer als Q, wenn es ein N gibt, so dass für alle n> = N, P (n) <= Q (n), und es mindestens ein n> = N gibt, so dass P (n) ) <Q (n). Wenn keines der Programme besser ist als das andere, sind sie gebunden. (Welches Programm langsamer ist, hängt im Wesentlichen vom Wert von lim (n-> ∞) P (n) -Q (n) ab.)
Die am langsamsten wachsende Funktion wird gemäß der Definition im vorherigen Absatz als diejenige definiert, die langsamer wächst als jede andere Funktion.
Dies ist Wachstum-Rate-Golf , also gewinnt das am langsamsten wachsende Programm!
Anmerkungen:
- Versuchen Sie, die von Ihrem Programm berechnete Funktion in die Antwort aufzunehmen, um die Bewertung zu erleichtern.
- Setzen Sie auch einige (theoretische) Ein- und Ausgaben ein, um den Leuten eine Vorstellung davon zu geben, wie langsam Sie fahren können.
quelle
<
gefolgt von einem Buchstaben der Anfang eines HTML-Tags ist.Antworten:
Haskell, 98 Bytes, Score = f ε 0 −1 ( n )
Wie es funktioniert
Dies berechnet die Umkehrung einer sehr schnell wachsenden Funktion im Zusammenhang mit Beklemishevs Wurmspiel . Die Wachstumsrate ist vergleichbar mit f ε 0 , wobei f α das ist schnell wachsende Hierarchie und & egr; 0 ist die erste epsilon Zahl .
Beachten Sie zum Vergleich mit anderen Antworten Folgendes
quelle
Brachylog , 100 Bytes
Probieren Sie es online!
Dies ist wahrscheinlich nicht annähernd die Langsamkeit einiger anderer ausgefallener Antworten, aber ich konnte nicht glauben, dass niemand diesen einfachen und schönen Ansatz ausprobiert hatte.
Wir berechnen einfach die Länge der eingegebenen Zahl, dann die Länge dieses Ergebnisses und dann die Länge dieses anderen Ergebnisses ... insgesamt 100 Mal.
Dies wächst so schnell wie log (log (log ... log (x), mit 100 Base-10-Protokollen.
Wenn Sie Ihre Zahl als Zeichenfolge eingeben , wird dies bei jeder Eingabe, die Sie versuchen könnten, extrem schnell ausgeführt, aber Sie dürfen nicht erwarten, jemals ein höheres Ergebnis als 1: D zu erhalten
quelle
JavaScript (ES6), Inverse Ackermann-Funktion *, 97 Bytes
* wenn ich es richtig gemacht habe
Funktion
A
ist die Ackermann-Funktion . Funktiona
soll die inverse Ackermann-Funktion sein . Wenn ich es richtig implementiert habe, sagt Wikipedia, dass es nicht treffen wird,5
bis esm
gleich ist2^2^2^2^16
. Ich kommeStackOverflow
herum1000
.Verwendung:
Erklärungen:
Ackermann-Funktion
Inverse Ackermann-Funktion
quelle
Pure Evil: Eval
Die Aussage in der eval erzeugt einen String mit einer Länge von 7 * 10 10 10 10 10 10 8,57 , die aus nichts besteht aber mehr Anrufe an die Lambda - Funktion , von denen jede eine Reihe von Konstrukt wird ähnliche Länge, weiter und weiter , bis schließlich
y
zu 0. Vordergründig Dies ist genauso komplex wie die unten beschriebene Eschew-Methode, aber anstatt sich auf die If- und / oder Control-Logik zu verlassen, werden nur riesige Strings zusammengestoßen (und das Nettoergebnis wird wahrscheinlich mehr gestapelt ...?).Der größte
y
Wert, den ich liefern und berechnen kann, ohne dass Python einen Fehler auslöst, ist 2, was bereits ausreicht, um eine Eingabe von max-float in die Rückgabe von 1 zu reduzieren.Eine Zeichenfolge der Länge 7.625.597.484.987 ist einfach zu groß:
OverflowError: cannot fit 'long' into an index-sized integer
.Ich sollte aufhören.
Eschew
Math.log
: Gehen Sie zur (10.) Wurzel (des Problems), Score: Funktion effektiv nicht unterscheidbar von y = 1.Durch das Importieren der Mathematikbibliothek wird die Anzahl der Bytes eingeschränkt. Heben wir das auf und ersetzen die
log(x)
Funktion durch etwas in etwa Äquivalentes:x**.1
Und das kostet ungefähr die gleiche Anzahl von Zeichen, erfordert aber keinen Import. Beide Funktionen haben eine sublineare Ausgabe in Bezug auf die Eingabe, aber x 0.1 wächst noch langsamer . Wir kümmern uns jedoch nicht viel darum, wir kümmern uns nur darum, dass es das gleiche Grundwachstumsmuster in Bezug auf große Zahlen hat, während es eine vergleichbare Anzahl von Zeichen verbraucht (z. B.x**.9
die gleiche Anzahl von Zeichen, wächst aber schneller, also dort ist ein Wert, der genau das gleiche Wachstum aufweisen würde).Was tun mit 16 Zeichen? Wie wäre es mit ... der Erweiterung unserer Lambda-Funktion auf Ackermann-Sequenzeigenschaften? Diese Antwort für große Zahlen hat diese Lösung inspiriert.
Der
z**z
Teil hier hindert mich daran, diese Funktion mit nahezu vernünftigen Eingaben für auszuführeny
undz
. Die größten Werte, die ich verwenden kann, sind 9 und 3, für die ich den Wert 1,0 zurückerhalte, selbst für die größten Float-Python-Unterstützungen (Anmerkung: while 1.0 Wenn der numerische Wert größer als 6,77538853089e-05 ist, verschieben erhöhte Rekursionsstufen die Ausgabe dieser Funktion näher an 1, bleiben jedoch größer als 1, während die vorherige Funktion Werte näher an 0 verschiebt und größer als 0 bleibt, was zu einer sogar moderaten Rekursion dieser Funktion führt führt zu so vielen Operationen, dass die Gleitkommazahl alle signifikanten Bits verliert .Neukonfiguration des ursprünglichen Lambda-Aufrufs mit Rekursionswerten von 0 und 2 ...
Wenn der Vergleich mit "Offset von 0" statt "Offset von 1" durchgeführt wird, gibt diese Funktion einen Wert zurück
7.1e-9
, der definitiv kleiner als ist6.7e-05
.Die tatsächlichen Programms Basis Rekursion (z - Wert) 10 10 10 10 1,97 Ebenen tief, sobald y erschöpft sich, es wird zurückgesetzt mit 10 10 10 10 10 1,97 (weshalb ein Anfangswert von 9 genügt), so dass ich don weiß nicht einmal, wie man die Gesamtzahl der auftretenden Rekursionen richtig berechnet: Ich habe das Ende meiner mathematischen Kenntnisse erreicht. Ebenso weiß ich nicht, ob das Verschieben einer der
**n
Exponentiationen von der anfänglichen Eingabe zur sekundärenz**z
die Anzahl der Rekursionen verbessern würde oder nicht (ebenso das Umkehren).Gehen wir noch langsamer mit noch mehr Rekursion
n//1
- Spart 2 Bytesint(n)
import math
,math.
spart 1 Byte mehrfrom math import*
a(...)
spart insgesamt 8 Bytesm(m,...)
(y>0)*x
Speichert ein Byte übery>0and x
9**9**99
erhöht Bytezahl um 4 erhöht und die Rekursion Tiefe von etwa2.8 * 10^x
wox
die alten Tiefe (oder eine Tiefe a googolplex Größe kurz vor: 10 10 94 ).9**9**9e9
Erhöht die Byteanzahl um 5 und die Rekursionstiefe um ... einen wahnsinnigen Betrag. Rekursionstiefe ist jetzt 10 10 10 9.93 , als Referenz, ein googolplex 10 10 10 2 .m(m(...))
aufa(a(a(...)))
Kosten 7 BytesNeuer Ausgabewert (bei 9 Rekursionstiefe):
Die Rekursionstiefe ist bis zu dem Punkt explodiert, an dem dieses Ergebnis buchstäblich bedeutungslos ist, außer im Vergleich zu den früheren Ergebnissen, die dieselben Eingabewerte verwenden:
log
25 Mal aufgerufenLambda Inception, Kerbe: ???
Ich habe gehört, Sie mögen Lambdas, so ...
Ich kann das nicht einmal ausführen, ich staple Überlauf sogar mit nur 99 Rekursionsebenen.
Die alte Methode (siehe unten) gibt Folgendes zurück (Überspringen der Konvertierung in eine Ganzzahl):
Die neue Methode gibt zurück und verwendet nur 9 Einbruchsebenen (anstelle des vollständigen Googols von ihnen):
Ich denke, dies ist ähnlich komplex wie die Ackerman-Sequenz, nur klein statt groß.
Auch dank ETHproductions für eine 3-Byte-Einsparung an Speicherplatz, von der ich nicht wusste, dass sie entfernt werden konnte.
Alte Antwort:
Die ganzzahlige Kürzung des Funktionsprotokolls (i + 1) wurde
20 bis25 Mal (Python) unter Verwendung von Lambda-Lambdas iteriert .PyRulez 'Antwort kann komprimiert werden, indem ein zweites Lambda eingeführt und gestapelt wird:
99100 Zeichen verwendet.Dies führt zu einer Iteration von
20 bis25 gegenüber dem Original 12. Außerdem werden 2 Zeichen gespart, indemint()
stattdessenfloor()
ein zusätzlicherx()
Stapel verwendet wird.Wenn die Leerzeichen nach dem Lambda entfernt werden können (das kann ich momentan nicht überprüfen),Möglich!y()
kann ein fünftel hinzugefügt werden.Wenn es eine Möglichkeit gibt, den
from math
Import zu überspringen, indem ein vollständig qualifizierter Name (z. B.x=lambda i: math.log(i+1))
) verwendet wird, werden dadurch noch mehr Zeichen gespeichert und ein weiterer Stapel von Zeichen ermöglichtx()
aber ich weiß nicht, ob Python solche Dinge unterstützt (ich vermute nicht). Getan!Dies ist im Wesentlichen derselbe Trick, der in XCKDs Blog-Post für große Zahlen verwendet wird , jedoch schließt der Mehraufwand bei der Deklaration von Lambdas einen dritten Stapel aus:
Dies ist die kleinstmögliche Rekursion mit 3 Lambdas, die die berechnete Stapelhöhe von 2 Lambdas überschreitet (wenn ein Lambda auf zwei Aufrufe reduziert wird, sinkt die Stapelhöhe auf 18, unter die der 2-Lambda-Version), erfordert jedoch leider 110 Zeichen.
quelle
int
Umstellung gezählt und dachte, ich hätte einige Ersatzteile.import
und den Raum danach entferneny<0
. Ich kenne zwar nicht viel Python, bin mir also nicht sichery<0and x or m(m,m(m,log(x+1),y-1),y-1)
, um ein weiteres Byte zu speichern (vorausgesetzt, esx
ist nie0
wanny<0
)log(x)
wächst langsamer als JEDE positive Potenz vonx
(für große Werte vonx
), und dies ist nicht schwer zu zeigen, wenn man die Regel von L'Hopital verwendet. Ich bin mir ziemlich sicher, dass Ihre aktuelle Version(...(((x**.1)**.1)**.1)** ...)
einige Male funktioniert . Aber diese Kräfte multiplizieren sich einfach, also ist es effektivx**(.1** (whole bunch))
, was eine (sehr kleine) positive Kraft von istx
. Das bedeutet, dass es tatsächlich schneller wächst als eine EINZELNE Iteration der Protokollfunktion (obwohl Sie sich SEHR große Werte ansehen müssten,x
bevor Sie es bemerken würden ... aber genau das meinen wir mit "Unendlich werden" ).Haskell , 100 Bytes
Probieren Sie es online!
Diese Lösung nimmt nicht die Umkehrung einer schnell wachsenden Funktion an, sondern nimmt in diesem Fall eine ziemlich langsam wachsende Funktion an
length.show
und wendet sie einige Male an.Zuerst definieren wir eine Funktion
f
.f
ist eine Bastard-Version von Knuths Uparrow-Notation, die etwas schneller wächst (ein bisschen untertrieben, aber die Zahlen, mit denen wir es zu tun haben, sind so groß, dass im großen Schema der Dinge ...). Wir definieren den Grundfall vonf 0 a b
Seina^b
odera
Seinb
. Wir definieren dann den allgemeinen Fall, der(f$c-1)
aufb+2
Instanzen von angewendet werden solla
. Wenn wir eine Knuth-Uparrow-Notation wie ein Konstrukt definieren würden, würden wir sie aufb
Instanzen von anwendena
, aber sieb+2
ist tatsächlich golfer und hat den Vorteil, dass sie schneller wächst.Wir definieren dann den Operator
#
.a#b
ist definiert, umlength.show
aufb
a
Zeiten angewendet zu werden . Jede Anwendung vonlength.show
ist ungefähr gleich log 10 , was keine sehr schnell wachsende Funktion ist.Anschließend definieren wir unsere Funktion
g
, die eine ganze Zahl aufnimmt und mehrerelength.show
Male auf die ganze Zahl anwendet . Um genau zu sein, gilt es fürlength.show
die Eingabef(f 9 9 9)9 9
. Bevor wir uns damit befassen, wie groß das ist, schauen wir uns das anf 9 9 9
.f 9 9 9
ist um ein Vielfaches größer als9↑↑↑↑↑↑↑↑↑9
(neun Pfeile). Ich glaube, es liegt irgendwo zwischen9↑↑↑↑↑↑↑↑↑9
(neun Pfeile) und9↑↑↑↑↑↑↑↑↑↑9
(zehn Pfeile). Nun ist dies eine unvorstellbar große Zahl, die viel zu groß ist, um auf einem existierenden Computer gespeichert zu werden (in binärer Notation). Wir nehmen das und setzen es als erstes Argument von unsf
, was bedeutet, dass unser Wert größer ist als9↑↑↑↑↑↑...↑↑↑↑↑↑9
beif 9 9 9
Pfeile dazwischen. Ich werde diese Zahl nicht beschreiben, weil sie so groß ist, dass ich nicht glaube, dass ich sie gerecht machen kann.Jedes entspricht
length.show
ungefähr der Logarithmusbasis 10 der ganzen Zahl. Dies bedeutet, dass die meisten Zahlen 1 zurückgeben, wennf
sie auf sie angewendet werden. Die kleinste Zahl, die etwas anderes als 110↑↑(f(f 9 9 9)9 9)
zurückgibt, ist 2. Denken wir einen Moment darüber nach. So abscheulich groß diese Zahl auch ist, so oft ist die kleinste Zahl, die 2 zurückgibt, 10 aus eigener Kraft. Das ist 1 gefolgt von10↑(f(f 9 9 9)9 9)
Nullen.Für den allgemeinen Fall
n
der kleinsten Eingabe muss die Ausgabe irgendeines gegebenen n sein(10↑(n-1))↑↑(f(f 9 9 9)9 9)
.Beachten Sie, dass dieses Programm viel Zeit und Speicher für selbst kleine n benötigt (mehr als es im Universum um ein Vielfaches gibt). Wenn Sie dies testen möchten, empfehle ich, es
f(f 9 9 9)9 9
durch eine viel kleinere Zahl zu ersetzen , versuchen Sie 1 oder 2, wenn Sie möchten bekomme jemals eine andere Ausgabe als 1.quelle
APL, Anwenden
log(n + 1)
,e^9^9...^9
mal, wobei die Länge der Kettee^9^9...^9
der Länge der Kette minus 1 mal entspricht, und so weiter.quelle
e^n^n...^n
Teil nicht sicher, also habe ich es zu einer Konstanten gemacht, aber es könnte wahr seinMATL , 42 Bytes
Probieren Sie es online!
Dieses Programm basiert auf der harmonischen Reihe unter Verwendung der Euler-Mascheroni-Konstante. Als ich die @ LuisMendo-Dokumentation in seiner MATL-Sprache las (mit Großbuchstaben, es sieht also wichtig aus), bemerkte ich diese Konstante. Der Ausdruck für die langsame Wachstumsfunktion lautet wie folgt:
wo εk ~ 1 / 2k
Ich habe bis zu 10000 Iterationen getestet (in Matlab, da es für TIO zu groß ist) und es wird mit unter 10 bewertet, daher ist es sehr langsam.
Erklärungen:
Empirischer Beweis: (ln k ) + 1 in Rot immer über ln k + γ + εk in Blau.
Das Programm für (ln k ) + 1 wurde in erstellt
Matlab,
471814 BytesInteressanterweise beträgt die verstrichene Zeit für n = 100 auf meinem Laptop 0,208693 Sekunden, aber nur 0,121945 Sekunden
d=rand(1,n);A=d*0;
und noch weniger 0,112147 SekundenA=zeros(1,n)
. Wenn Nullen Platzverschwendung sind, spart das Geschwindigkeit! Aber ich weiche vom Thema ab (wahrscheinlich sehr langsam).Edit: Danke an Stewie, der dabei
geholfen hat, diesen Matlab-Ausdruck auf einfach zu reduzieren:quelle
n=input('');A=log(1:n)+1
, oder als unbenannte anonyme Funktion (14 Byte):@(n)log(1:n)+1
. Ich bin mir bei MATLAB nicht sicher,A=log(1:input(''))+1
arbeite aber in Octave ...n=input('');A=log(1:n)+1
funktioniert,@(n)log(1:n)+1
nicht (in der Tat eine gültige Funktion mit Handle in Matlab, aber die Eingabe wird nicht gefragt),A=log(1:input(''))+1
funktioniert und kann gekürzt werdenlog(1:input(''))+1
f=
nicht gezählt werden, da es möglich ist, nur zu:@(n)log(1:n)+1
gefolgt vonans(10)
, um die ersten 10 Zahlen zu erhalten.Python 3 , 100 Bytes
Die Etage des Funktionsprotokolls (i + 1) wurde 999999999999999999999999999999999999999 mal durchlaufen.
Man kann Exponenten verwenden, um die obige Zahl noch größer zu machen ...
Probieren Sie es online!
quelle
9**9**9**...**9**9e9
?Der Fußboden des Funktionsprotokolls (i + 1) wurde 14-mal wiederholt (Python)
Ich erwarte nicht, dass dies sehr gut funktioniert, aber ich dachte, es ist ein guter Anfang.
Beispiele:
quelle
int
anstelle von verwendenfloor
, können Sie in eine andere passenx(
e^e^e^e...^n
? Auch warum gibt es ein Leerzeichen nach dem:
?x()
Anruf hinzufügen können ?Rubin, 100 Bytes, score -1 = f & ohgr; & ohgr; 1 + (n 2 )
Grundsätzlich von meiner größten druckbaren Nummer ausgeliehen , hier ist mein Programm:
Probieren Sie es online aus
Berechnet grundsätzlich die Inverse von f ω ω + 1 (n 2 ) in der schnell wachsenden Hierarchie. Die ersten Werte sind
Und dann wird noch
2
sehr lange ausgegeben . Sogarx[G] = 2
, woG
ist Grahams Nummer?quelle
Mathematica, 99 Bytes
(unter der Annahme, dass ± 1 Byte dauert)
Die ersten 3 Befehle definieren
x±y
die AuswertungAckermann(y, x)
.Das Ergebnis der Funktion ist,
f(#)=#±#±#±#±#±#±#±#
wie oft auf 1 angewendet werden muss, bevor der Wert den Wert des Parameters erreicht. Daf(#)=#±#±#±#±#±#±#±#
(das heißtf(#)=Ackermann[Ackermann[Ackermann[Ackermann[Ackermann[Ackermann[Ackermann[#, #], #], #], #], #], #], #]
) sehr schnell wächst , wächst die Funktion sehr langsam.quelle
Clojure, 91 Bytes
Art berechnet das
sum 1/(n * log(n) * log(log(n)) * ...)
, was ich hier gefunden habe . Da die Funktion jedoch 101 Byte lang war, musste ich die explizite Anzahl der Iterationen löschen und stattdessen iterieren, solange die Anzahl größer als eins ist. Beispielausgaben für Eingaben von10^i
:Ich gehe davon aus, dass diese modifizierte Serie immer noch divergiert, aber jetzt weiß ich, wie ich es beweisen kann.
quelle
Javascript (ES6), 94 Byte
Erklärung :
Id
verweistx => x
im Folgenden auf.Werfen wir zunächst einen Blick auf:
p(Math.log)
ist ungefähr gleichlog*(x)
.p(p(Math.log))
ist ungefähr gleichlog**(x)
(Anzahl von Malen, die Sie nehmen können,log*
bis der Wert höchstens 1 ist).p(p(p(Math.log)))
ist ungefähr gleichlog***(x)
.Die inverse Ackermann-Funktion entspricht
alpha(x)
in etwa der Mindestanzahl von Kompositionen,p
bis der Wert höchstens 1 beträgt.Wenn wir dann verwenden:
dann können wir schreiben
alpha = p(Id)(Math.log)
.Das ist jedoch ziemlich langweilig. Erhöhen wir also die Anzahl der Ebenen:
Das ist so, wie wir konstruiert haben
alpha(x)
, außer dasslog**...**(x)
wir es jetzt tun , anstatt es zu tunalpha**...**(x)
.Warum hier aufhören?
Wenn die vorherige Funktion ist
f(x)~alpha**...**(x)
, ist diese jetzt~ f**...**(x)
. Wir tun noch eine Stufe, um unsere endgültige Lösung zu erhalten.quelle
p(p(x => x - 2))
msgstr " ist ungefähr gleichlog**(x)
(Anzahl von Malen, die Sie nehmen können,log*
bis der Wert höchstens 1 ist)". Ich verstehe diese Aussage nicht. Meiner Meinung nachp(x => x - 2)
sollte dies "die Anzahl der Subtraktionen sein,2
bis der Wert höchstens 1 beträgt". Das heißt, p (x => x - 2) `sollte die Funktion" Teilen durch 2 "sein. Daherp(p(x => x - 2))
sollte "die Anzahl der Male, die Sie durch 2 teilen können, bis der Wert höchstens 1 ist" sein ... das heißt, es sollte dielog
Funktion sein, nichtlog*
oderlog**
. Vielleicht könnte dies geklärt werden?p = f => x => x < 2 ? 0 : 1 + p(p(f))(f(x))
, wop
übergeben wird ,p(f)
wie in den anderen Linien, nichtf
.