Чистое Зло: 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
Оператор внутри eval создает строку длиной 7 * 10 10 10 10 10 10 8.57, которая состоит из не более чем дополнительных вызовов лямбда-функции, каждый из которых будет создавать строку одинаковой длины, до тех пор, пока в конечном итоге не y
станет 0. Якобы это имеет ту же сложность, что и метод Эшью, описанный ниже, но вместо того, чтобы полагаться на логику управления «если и / или», он просто объединяет гигантские строки (и в результате получается больше стеков… вероятно?).
Наибольшее y
значение, которое я могу предоставить и вычислить без Python, выдающего ошибку, равно 2, что уже достаточно, чтобы уменьшить ввод max-float для возврата 1.
Строка длины 7,625,597,484,987 слишком велик: OverflowError: cannot fit 'long' into an index-sized integer
.
Я должен остановиться.
Eschew Math.log
: Переходя к (10-му) корню (проблемы), Score: функция эффективно неотличима от y = 1.
Импорт математической библиотеки ограничивает количество байтов. Давайте покончим с этим и заменим log(x)
функцию чем-то примерно эквивалентным: x**.1
и которая стоит примерно столько же символов, но не требует импорта. Обе функции имеют сублинейный вывод относительно ввода, но x 0,1 растет еще медленнее . Однако нас это не сильно волнует, мы заботимся только о том, чтобы у него была одинаковая базовая схема роста по отношению к большим числам при одновременном потреблении сопоставимого количества символов (например, x**.9
такое же количество символов, но растет быстрее, поэтому это некоторая ценность, которая будет демонстрировать точно такой же рост).
Теперь, что делать с 16 символами. Как насчет ... расширения нашей лямбда-функции, чтобы иметь свойства последовательности Аккермана? Этот ответ для большого числа вдохновил это решение.
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
В этой z**z
части я не могу запускать эту функцию в местах, близких к нормальным входам для y
и z
, наибольшие значения, которые я могу использовать, равны 9 и 3, для которых я получаю значение 1,0, даже для наибольшего числа с плавающей запятой, поддерживаемого Python (примечание: пока 1,0 численно больше, чем 6.77538853089e-05, повышенные уровни рекурсии перемещают выход этой функции ближе к 1, оставаясь больше 1, тогда как предыдущая функция перемещала значения ближе к 0, оставаясь больше 0, таким образом, даже умеренная рекурсия для этой функции приводит к такому количеству операций, что число с плавающей запятой теряет все значащие биты).
Переконфигурирование исходного лямбда-вызова для получения значений рекурсии 0 и 2 ...
>>>1.7976931348623157e+308
1.0000000071
Если сравнение выполняется для «смещения от 0» вместо «смещения от 1», эта функция возвращает значение 7.1e-9
, которое определенно меньше, чем 6.7e-05
.
Реальная базовая рекурсия программы (значение z) имеет глубину 10 10 10 10 1,97 уровня, и как только y исчерпывает себя, она сбрасывается с 10 10 10 10 10 1,97 (именно поэтому начальное значение 9 достаточно), поэтому я не буду Я даже не знаю, как правильно рассчитать общее количество рекурсий, которые произошли: я достиг конца своих математических знаний. Точно так же я не знаю, улучшило бы число рекурсий перемещение одного **n
возведения в степень от начального входа к вторичному z**z
(или наоборот).
Пойдем еще медленнее с еще большей рекурсией
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
- экономит 2 байта int(n)
import math
, math.
сохраняет 1 байтfrom math import*
a(...)
более 8 байтов m(m,...)
(y>0)*x
сохраняет байт за кадромy>0and x
9**9**99
увеличивается количество байт на 4 и увеличивает глубину рекурсии примерно , 2.8 * 10^x
где x
старая глубина (или глубина приближается к гуголплексу в размере: 10 10 94 ).
9**9**9e9
увеличивает количество байтов на 5 и увеличивает глубину рекурсии на ... безумное количество. Глубина рекурсии теперь 10 10 10 9,93 , для справки, googolplex - 10 10 10 2 .
- Лямбда декларация увеличивает рекурсию на дополнительный шаг:
m(m(...))
на a(a(a(...)))
затраты 7 байт
Новое выходное значение (на глубине 9 рекурсий):
>>>1.7976931348623157e+308
6.77538853089e-05
Глубина рекурсии взорвалась до такой степени, что этот результат буквально не имеет смысла, за исключением сравнения с более ранними результатами, использующими те же входные значения:
- Оригинал называется
log
25 раз
- Первое улучшение называет это 81 раз
- Текущая программа будет называть его 1e99 2 или около 10 10 2,3 раза
- Эта версия называет это 729 раз
- Текущая программа будет называть его (9 - 99 ) 3 или немного меньше , чем 10 10 95 раз).
Lambda Inception, оценка: ???
Я слышал, что вы любите лямбды, так что ...
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))
Я даже не могу запустить это, я переполняю стек даже с 99 уровнями рекурсии.
Старый метод (ниже) возвращает (пропуская преобразование в целое число):
>>>1.7976931348623157e+308
0.0909072713593
Новый метод возвращает, используя только 9 слоев вторжения (а не полный гугол из них):
>>>1.7976931348623157e+308
0.00196323936205
Я думаю, что это имеет ту же сложность, что и последовательность Акермана, только маленькая, а не большая.
Также благодаря ETHproductions для 3-байтовой экономии в пространствах, которые я не знал, можно было удалить.
Старый ответ:
Целочисленное усечение функции log (i + 1) повторялось 20 25 раз (Python), используя лямбда-лямбды.
Ответ PyRulez можно сжать, введя вторую лямбду и сложив ее:
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 символов используется.
В результате получается итерация 20 25 по сравнению с исходной 12. Кроме того, он сохраняет 2 символа, используя int()
вместо floor()
которых допускается дополнительный x()
стек. Если пробелы после лямбды можно убрать (я не могу проверить в данный момент), то y()
можно добавить пятую. Возможный!
Если есть способ пропустить from math
импорт, используя полностью определенное имя (например x=lambda i: math.log(i+1))
), это позволило бы сохранить еще больше символов и позволить другой стек, x()
но я не знаю, поддерживает ли Python такие вещи (я подозреваю, что нет). Выполнено!
По сути, это та же самая хитрость, которая использовалась в блоге XCKD для больших чисел , однако накладные расходы при объявлении лямбды исключают третий стек:
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()))))
Это наименьшая возможная рекурсия с 3 лямбдами, которая превышает вычисленную высоту стека в 2 лямбды (сокращение любой лямбды до двух вызовов снижает высоту стека до 18, по сравнению с версией с 2 лямбдами), но, к сожалению, требует 110 символов.