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
La declaración dentro de la evaluación crea una cadena de longitud 7 * 10 10 10 10 10 10 8.57 que consiste en nada más que más llamadas a la función lambda, cada una de las cuales construirá una cadena de longitud similar , una y otra vez hasta que finalmentey
convierta en 0. Ostensiblemente esto tiene la misma complejidad que el método Eschew a continuación, pero en lugar de depender de la lógica de si y o control, simplemente rompe cadenas gigantes juntas (y el resultado neto es obtener más pilas ... ¿probablemente?).
El y
valor más grande que puedo suministrar y calcular sin que Python arroje un error es 2, que ya es suficiente para reducir una entrada de max-float para devolver 1.
Una serie de longitud 7.625.597.484.987 es demasiado grande: OverflowError: cannot fit 'long' into an index-sized integer
.
Yo debería dejar de.
Esquiar Math.log
: Ir a la raíz (10º) (del problema), Puntuación: función efectivamente indistinguible de y = 1.
La importación de la biblioteca matemática está restringiendo el recuento de bytes. Vamos a eliminar eso y reemplazar la log(x)
función con algo más o menos equivalente: x**.1
y que cuesta aproximadamente el mismo número de caracteres, pero no requiere la importación. Ambas funciones tienen una salida sublineal con respecto a la entrada, pero x 0.1 crece aún más lentamente . Sin embargo, no nos importa mucho, solo nos importa que tenga el mismo patrón de crecimiento base con respecto a grandes números mientras consume una cantidad comparable de caracteres (por ejemplo, x**.9
es la misma cantidad de caracteres, pero crece más rápidamente, por lo que hay es un valor que exhibiría exactamente el mismo crecimiento).
Ahora, qué hacer con 16 personajes. ¿Qué tal ... extender nuestra función lambda para tener propiedades de secuencia de Ackermann? Esta respuesta para grandes números inspiró esta solución.
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
porción aquí me impide ejecutar esta función con cualquier lugar cercano a las entradas sensatas para y
y z
, los valores más grandes que puedo usar son 9 y 3 para los cuales obtengo el valor de 1.0, incluso para los soportes más grandes flotantes de Python (nota: while 1.0 es numéricamente mayor que 6.77538853089e-05, el aumento de los niveles de recursión mueve la salida de esta función más cerca de 1, mientras permanece mayor que 1, mientras que la función anterior movió los valores más cerca de 0 mientras permanece mayor que 0, por lo tanto, incluso una recursión moderada en esta función da como resultado tantas operaciones que el número de coma flotante pierde todos los bits significativos).
Reconfigurando la llamada lambda original para tener valores de recursividad de 0 y 2 ...
>>>1.7976931348623157e+308
1.0000000071
Si la comparación se realiza para "compensar desde 0" en lugar de "compensar desde 1", esta función regresa 7.1e-9
, que es definitivamente más pequeña que 6.7e-05
.
La recursión base del programa real (valor z) es 10 10 10 10 1.97 niveles profundos, tan pronto como y se agota, se restablece con 10 10 10 10 10 1.97 (por lo que un valor inicial de 9 es suficiente), así que no Ni siquiera sé cómo calcular correctamente el número total de recursiones que ocurren: he llegado al final de mi conocimiento matemático. Del mismo modo, no sé si mover una de las **n
exponenciaciones de la entrada inicial a la secundaria z**z
mejoraría o no el número de recursiones (ídem al revés).
Vayamos aún más lento con aún más recursividad
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
- ahorra 2 bytes sobre int(n)
import math
, math.
ahorra 1 byte sobrefrom math import*
a(...)
ahorra 8 bytes en total m(m,...)
(y>0)*x
ahorra un byte másy>0and x
9**9**99
aumenta el recuento de bytes en 4 y aumenta la profundidad de recursión en aproximadamente 2.8 * 10^x
dónde x
está la profundidad anterior (o una profundidad cercana al tamaño de un googolplex: 10 10 94 ).
9**9**9e9
aumenta el número de bytes en 5 y aumenta la profundidad de recursión en ... una cantidad increíble. La profundidad de recursión es ahora 10 10 10 9.93 , para referencia, un googolplex es 10 10 10 2 .
- Declaración lambda aumenta la recursividad por un paso adicional:
m(m(...))
a a(a(a(...)))
los costos de 7 bytes
Nuevo valor de salida (a 9 profundidades de recursión):
>>>1.7976931348623157e+308
6.77538853089e-05
La profundidad de recursión ha explotado hasta el punto en que este resultado es literalmente sin sentido, excepto en comparación con los resultados anteriores que utilizan los mismos valores de entrada:
- El original llamado
log
25 veces
- La primera mejora lo llama 81 veces
- El programa real lo llamaría 1e99 2 o aproximadamente 10 10 2.3 veces
- Esta versión lo llama 729 veces
- El programa real lo llamaría (9 9 99 ) 3 o un poco menos de 10 10 95 veces).
Lambda Inception, puntuación: ???
Te escuché como lambdas, así que ...
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))
Ni siquiera puedo ejecutar esto, apilo el desbordamiento incluso con solo 99 capas de recursión.
El método anterior (a continuación) regresa (omitiendo la conversión a un entero):
>>>1.7976931348623157e+308
0.0909072713593
El nuevo método regresa, usando solo 9 capas de incursión (en lugar del googol completo de ellas):
>>>1.7976931348623157e+308
0.00196323936205
Creo que esto resulta ser de una complejidad similar a la secuencia de Ackerman, solo pequeña en lugar de grande.
También gracias a ETHproductions por un ahorro de 3 bytes en espacios que no sabía que podrían eliminarse.
Vieja respuesta:
El truncamiento de enteros del registro de funciones (i + 1) iteró 20 25 veces (Python) usando lambda'd lambdas.
La respuesta de PyRulez se puede comprimir introduciendo una segunda lambda y apilándola:
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 caracteres utilizados.
Esto produce una iteración de 20 25, sobre el original 12. Además, ahorra 2 caracteres al usar en int()
lugar de lo floor()
que permite una x()
pila adicional . Si los espacios después de la lambda se pueden eliminar (no puedo verificar en este momento), y()
se puede agregar un quinto . ¡Posible!
Si hay una manera de omitir la from math
importación mediante el uso de un nombre completo (por ejemplo x=lambda i: math.log(i+1))
), eso ahorraría aún más caracteres y permitiría otra pila dex()
pero no sé si Python admite tales cosas (sospecho que no). ¡Hecho!
Este es esencialmente el mismo truco utilizado en la publicación de blog de XCKD en grandes cantidades , sin embargo, la sobrecarga al declarar lambdas impide una tercera pila:
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()))))
Esta es la recursión más pequeña posible con 3 lambdas que excede la altura de la pila calculada de 2 lambdas (al reducir cualquier lambda a dos llamadas, la altura de la pila cae a 18, por debajo de la versión de 2 lambda), pero desafortunadamente requiere 110 caracteres.