Pure Evil: Eval
a=lambda x,y:(y<0)*x or eval("a("*9**9**9+"x**.1"+",y-1)"*9**9**9)
print a(input(),9**9**9**9**9)//1
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.
a=lambda x,y,z:(z<0)*x or y and a(x**.1,z**z,z-1)or a(x**.1,y-1,z)
print a(input(),9,9**9**9**99)//1
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 ...
>>>1.7976931348623157e+308
1.0000000071
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 ist 6.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ären z**z
die Anzahl der Rekursionen verbessern würde oder nicht (ebenso das Umkehren).
Gehen wir noch langsamer mit noch mehr Rekursion
import math
a=lambda x,y:(y<0)*x or a(a(a(math.log(x+1),y-1),y-1),y-1)
print a(input(),9**9**9e9)//1
n//1
- Spart 2 Bytes int(n)
import math
,math.
spart 1 Byte mehrfrom math import*
a(...)
spart insgesamt 8 Bytes m(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 etwa 2.8 * 10^x
wo x
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 .
- Lambda Erklärung erhöht Rekursion durch einen zusätzlichen Schritt:
m(m(...))
auf a(a(a(...)))
Kosten 7 Bytes
Neuer Ausgabewert (bei 9 Rekursionstiefe):
>>>1.7976931348623157e+308
6.77538853089e-05
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:
- Das Original wurde
log
25 Mal aufgerufen
- Die erste Verbesserung nennt es 81 Mal
- Das tatsächliche Programm würde es 1e99 2 oder ungefähr 10 10 2,3 mal aufrufen
- Diese Version nennt es 729 mal
- Das tatsächliche Programm würde es (9 9 99 ) 3 oder etwas weniger als 10 10 95 Mal aufrufen ).
Lambda Inception, Kerbe: ???
Ich habe gehört, Sie mögen Lambdas, so ...
from math import*
a=lambda m,x,y:y<0and x or m(m,m(m,log(x+1),y-1),y-1)
print int(a(a,input(),1e99))
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):
>>>1.7976931348623157e+308
0.0909072713593
Die neue Methode gibt zurück und verwendet nur 9 Einbruchsebenen (anstelle des vollständigen Googols von ihnen):
>>>1.7976931348623157e+308
0.00196323936205
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 bis 25 Mal (Python) unter Verwendung von Lambda-Lambdas iteriert .
PyRulez 'Antwort kann komprimiert werden, indem ein zweites Lambda eingeführt und gestapelt wird:
from math import *
x=lambda i:log(i+1)
y=lambda i:x(x(x(x(x(i)))))
print int(y(y(y(y(y(input()))))))
99 100 Zeichen verwendet.
Dies führt zu einer Iteration von 20 bis 25 gegenüber dem Original 12. Außerdem werden 2 Zeichen gespart, indem int()
stattdessen floor()
ein zusätzlicher x()
Stapel verwendet wird. Wenn die Leerzeichen nach dem Lambda entfernt werden können (das kann ich momentan nicht überprüfen), y()
kann ein fünftel hinzugefügt werden. Möglich!
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:
from math import *
x=lambda i:log(i+1)
y=lambda i:x(x(x(i)))
z=lambda i:y(y(y(i)))
print int(z(z(z(input()))))
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.