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
L'instruction à l'intérieur de l'éval crée une chaîne de longueur 7 * 10 10 10 10 10 10 8.57 qui se compose de rien mais plus d'appels à la fonction lambda dont chacun construira une chaîne de longueur similaire , y
indéfiniment jusqu'à ce qu'elle devienne finalement 0. Ostensiblement cela a la même complexité que la méthode Eschew ci-dessous, mais plutôt que de s'appuyer sur une logique de contrôle si et / ou, il écrase simplement des chaînes géantes (et le résultat net obtient plus de piles ... probablement?).
La plus grande y
valeur que je puisse fournir et calculer sans que Python ne génère d'erreur est 2, ce qui est déjà suffisant pour réduire une entrée de max-float en renvoyant 1.
Une chaîne de longueur 7.625.597.484.987 est trop grand: OverflowError: cannot fit 'long' into an index-sized integer
.
Je devrais m'arrêter.
Eschew Math.log
: Aller à la racine (10e) (du problème), Score: fonction effectivement indiscernable de y = 1.
L'importation de la bibliothèque mathématique limite le nombre d'octets. Supprimons cela et remplaçons la log(x)
fonction par quelque chose à peu près équivalent: x**.1
et qui coûte environ le même nombre de caractères, mais ne nécessite pas l'importation. Les deux fonctions ont une sortie sublinéaire par rapport à l'entrée, mais x 0,1 croît encore plus lentement . Cependant, nous ne nous soucions pas beaucoup, nous nous soucions seulement du fait qu'il a le même schéma de croissance de base en ce qui concerne les grands nombres tout en consommant un nombre comparable de caractères (par exemple, x**.9
est le même nombre de caractères, mais croît plus rapidement, donc il est une valeur qui présenterait exactement la même croissance).
Maintenant, que faire avec 16 caractères. Que diriez-vous ... d'étendre notre fonction lambda pour avoir des propriétés de séquence Ackermann? Cette réponse pour un grand nombre a inspiré cette solution.
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
La z**z
partie ici m'empêche d'exécuter cette fonction avec n'importe où près d'entrées saines pour y
et z
, les plus grandes valeurs que je peux utiliser sont 9 et 3 pour lesquelles je récupère la valeur de 1,0, même pour les plus grands supports flottants Python (note: tandis que 1.0 est numériquement supérieur à 6,77538853089e-05, l'augmentation des niveaux de récursivité rapproche la sortie de cette fonction de 1, tout en restant supérieure à 1, tandis que la fonction précédente rapprochait les valeurs de 0 tout en restant supérieure à 0, donc même une récursion modérée sur cette fonction entraîne tellement d'opérations que le nombre à virgule flottante perd tous les bits significatifs).
Reconfiguration de l'appel lambda d'origine pour avoir des valeurs de récursivité de 0 et 2 ...
>>>1.7976931348623157e+308
1.0000000071
Si la comparaison est faite à "décalage de 0" au lieu de "décalage de 1", cette fonction retourne 7.1e-9
, ce qui est nettement inférieur à 6.7e-05
.
La récursion de base du programme réel (valeur z) est profonde de 10 10 10 10 1,97 , dès que y s'épuise, il est réinitialisé avec 10 10 10 10 10 1,97 (ce qui explique pourquoi une valeur initiale de 9 est suffisante), donc je ne ne sais même pas comment calculer correctement le nombre total de récursions qui se produisent: j'ai atteint la fin de mes connaissances mathématiques. De même je ne sais pas si déplacer une des **n
exponentiations de l'entrée initiale vers le secondaire z**z
améliorerait ou non le nombre de récursions (idem inverse).
Permet d'aller encore plus lentement avec encore plus de récursivité
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
- enregistre 2 octets de plus int(n)
import math
, math.
enregistre 1 octet de plusfrom math import*
a(...)
enregistre 8 octets au total sur m(m,...)
(y>0)*x
enregistre un octet sury>0and x
9**9**99
augmente le nombre d'octets de 4 et augmente la profondeur de récursivité approximativement 2.8 * 10^x
où se x
trouve l'ancienne profondeur (ou une profondeur proche d'un googolplex de taille: 10 10 94 ).
9**9**9e9
augmente le nombre d'octets de 5 et augmente la profondeur de récursivité de ... une quantité folle. La profondeur de récursivité est maintenant de 10 10 10 9,93 , pour référence, un googolplex est de 10 10 10 2 .
- déclaration lambda augmente récursion par une étape supplémentaire:
m(m(...))
pour les a(a(a(...)))
coûts 7 octets
Nouvelle valeur de sortie (à 9 profondeurs de récursivité):
>>>1.7976931348623157e+308
6.77538853089e-05
La profondeur de récursivité a explosé au point où ce résultat est littéralement dénué de sens, sauf en comparaison avec les résultats précédents utilisant les mêmes valeurs d'entrée:
- L'original appelé
log
25 fois
- La première amélioration l'appelle 81 fois
- Le programme actuel l'appellerait 1e99 2 ou environ 10 10 2,3 fois
- Cette version l'appelle 729 fois
- Le programme réel l'appellerait (9 9 99 ) 3 ou un peu moins de 10 10 95 fois).
Lambda Inception, score: ???
Je t'ai entendu comme des lambdas, alors ...
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))
Je ne peux même pas exécuter cela, j'empile le débordement même avec seulement 99 couches de récursivité.
L'ancienne méthode (ci-dessous) renvoie (en ignorant la conversion en un entier):
>>>1.7976931348623157e+308
0.0909072713593
La nouvelle méthode revient, en utilisant seulement 9 couches d'incursion (plutôt que le googol complet ):
>>>1.7976931348623157e+308
0.00196323936205
Je pense que cela a une complexité similaire à la séquence Ackerman, seulement petite au lieu de grande.
Merci aussi à ETHproductions pour une économie de 3 octets dans des espaces que je ne pensais pas pouvoir supprimer.
Ancienne réponse:
La troncature entière du journal de fonction (i + 1) a été répétée 20 à 25 fois (Python) en utilisant des lambdas lambda.
La réponse de PyRulez peut être compressée en introduisant un deuxième lambda et en l'empilant:
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 caractères utilisés.
Cela produit une itération de 20 25, au-dessus de l'original 12. En outre, il enregistre 2 caractères en utilisant int()
au lieu de floor()
ce qui permettait une x()
pile supplémentaire . Si les espaces après le lambda peuvent être supprimés (je ne peux pas vérifier pour le moment), un 5ème y()
peut être ajouté. Possible!
S'il existe un moyen d'ignorer l' from math
importation en utilisant un nom complet (par exemple x=lambda i: math.log(i+1))
), cela économiserait encore plus de caractères et permettrait une autre pile de x()
mais je ne sais pas si Python prend en charge de telles choses (je ne le pense pas). Terminé!
C'est essentiellement la même astuce que celle utilisée dans le blog de XCKD sur les grands nombres , mais la surcharge de déclaration des lambdas empêche une troisième pile:
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()))))
Il s'agit de la plus petite récursivité possible avec 3 lambdas qui dépasse la hauteur de pile calculée de 2 lambdas (la réduction de tout lambda à deux appels fait chuter la hauteur de pile à 18, en dessous de celle de la version 2-lambda), mais nécessite malheureusement 110 caractères.