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
Pernyataan di dalam eval menciptakan string dengan panjang 7 * 10 10 10 10 10 10 8.57 yang hanya terdiri dari panggilan ke fungsi lambda yang masing-masing akan membangun string dengan panjang yang sama , terus dan terus hingga akhirnya y
menjadi 0. Seolah-olah ini memiliki kompleksitas yang sama dengan metode Eschew di bawah ini, tetapi daripada mengandalkan logika jika-dan-atau, itu hanya menghancurkan string raksasa bersama-sama (dan hasil bersihnya menjadi lebih banyak tumpukan ... mungkin?).
Nilai terbesar yang y
dapat saya berikan dan hitung tanpa Python melemparkan kesalahan adalah 2 yang sudah cukup untuk mengurangi input max-float menjadi pengembalian 1.
Sebuah string panjang 7.625.597.484.987 terlalu besar: OverflowError: cannot fit 'long' into an index-sized integer
.
Saya harus berhenti.
Eschew Math.log
: Pergi ke root (ke-10) (dari masalah), Score: berfungsi secara efektif tidak dapat dibedakan dari y = 1.
Mengimpor perpustakaan matematika membatasi jumlah byte. Mari kita hilangkan itu dan ganti log(x)
fungsinya dengan sesuatu yang kira-kira setara: x**.1
dan yang harganya kira-kira jumlah karakter yang sama, tetapi tidak memerlukan impor. Kedua fungsi memiliki output sublinear sehubungan dengan input, tetapi x 0,1 tumbuh lebih lambat . Namun kami tidak terlalu peduli, kami hanya peduli bahwa ia memiliki pola pertumbuhan basis yang sama sehubungan dengan jumlah besar sambil mengkonsumsi jumlah karakter yang sebanding (mis. x**.9
Jumlah karakter yang sama, tetapi tumbuh lebih cepat, jadi ada adalah beberapa nilai yang akan menunjukkan pertumbuhan yang sama persis).
Sekarang, apa yang harus dilakukan dengan 16 karakter. Bagaimana kalau ... memperluas fungsi lambda kita untuk memiliki properti Sequence Ackermann? Jawaban untuk sejumlah besar ini menginspirasi solusi ini.
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
The z**z
porsi disini mencegah saya dari menjalankan fungsi ini dengan di mana saja dekat dengan masukan waras untuk y
dan z
, nilai-nilai terbesar yang bisa saya gunakan adalah 9 dan 3 yang saya mendapatkan kembali nilai 1,0, bahkan untuk terbesar mendukung mengapung Python (catatan: sementara 1.0 secara numerik lebih besar dari 6,77538853089e-05, peningkatan level rekursi memindahkan output fungsi ini lebih dekat ke 1, sementara tetap lebih besar dari 1, sedangkan fungsi sebelumnya memindahkan nilai lebih dekat ke 0 sementara tetap lebih besar dari 0, sehingga bahkan rekursi moderat pada fungsi ini menghasilkan begitu banyak operasi sehingga angka floating point kehilangan semua bit signifikan).
Mengkonfigurasi ulang panggilan lambda asli untuk memiliki nilai rekursi 0 dan 2 ...
>>>1.7976931348623157e+308
1.0000000071
Jika perbandingan dibuat untuk "offset dari 0" alih-alih "offset dari 1" fungsi ini kembali 7.1e-9
, yang pasti lebih kecil dari 6.7e-05
.
Rekursi dasar program aktual (nilai z) adalah 10 10 10 10 1,97 level, begitu y melelahkan, ia akan direset dengan 10 10 10 10 10 1,97 (itulah sebabnya nilai awal 9 cukup), jadi saya tidak bahkan tidak tahu bagaimana menghitung dengan benar jumlah rekursi yang terjadi: saya telah mencapai akhir dari pengetahuan matematika saya. Demikian pula saya tidak tahu apakah memindahkan salah satu **n
eksponensial dari input awal ke sekunder z**z
akan meningkatkan jumlah rekursi atau tidak (ditto reverse).
Mari kita lebih lambat dengan lebih banyak rekursi
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
- menghemat 2 byte lebih int(n)
import math
, math.
menghemat 1 byte lebihfrom math import*
a(...)
menghemat total 8 byte m(m,...)
(y>0)*x
menghemat satu byte lebihy>0and x
9**9**99
meningkatkan jumlah byte sebanyak 4 dan meningkatkan kedalaman rekursi sekitar kira-kira di 2.8 * 10^x
mana x
kedalaman yang lama (atau kedalaman yang mendekati ukuran googolplex: 10 10 94 ).
9**9**9e9
meningkatkan jumlah byte sebesar 5 dan meningkatkan kedalaman rekursi sebesar ... jumlah yang gila. Kedalaman rekursi sekarang 10 10 10 9,93 , untuk referensi, googolplex adalah 10 10 10 2 .
- deklarasi lambda meningkatkan rekursi dengan langkah ekstra:
m(m(...))
dengan a(a(a(...)))
biaya 7 byte
Nilai output baru (pada kedalaman 9 rekursi):
>>>1.7976931348623157e+308
6.77538853089e-05
Kedalaman rekursi telah meledak ke titik di mana hasil ini benar - benar tidak berarti kecuali dibandingkan dengan hasil sebelumnya menggunakan nilai input yang sama:
- Aslinya disebut
log
25 kali
- Perbaikan pertama menyebutnya 81 kali
- Program yang sebenarnya akan menyebutnya 1e99 2 atau sekitar 10 10 2,3 kali
- Versi ini menyebutnya 729 kali
- Program yang sebenarnya akan menyebutnya (9 9 99 ) 3 atau sedikit kurang dari 10 10 95 kali).
Lambda Inception, skor: ???
Saya mendengar Anda suka lambdas, jadi ...
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))
Saya bahkan tidak bisa menjalankan ini, saya menumpuk melimpah bahkan dengan 99 lapisan rekursi.
Metode lama (di bawah) mengembalikan (melewatkan konversi ke integer):
>>>1.7976931348623157e+308
0.0909072713593
Metode baru kembali, menggunakan hanya 9 lapisan serangan (bukan googol penuh dari mereka):
>>>1.7976931348623157e+308
0.00196323936205
Saya pikir ini bekerja dengan kompleksitas yang mirip dengan urutan Ackerman, hanya kecil, bukan besar.
Juga berkat produk ETH untuk penghematan 3 byte di ruang yang saya tidak sadari dapat dihapus.
Jawaban lama:
Pemotongan integer dari fungsi log (i + 1) iterasi 20 25 kali (Python) menggunakan lambda'd lambdas.
Jawaban PyRulez dapat dikompres dengan memperkenalkan lambda kedua dan menumpuknya:
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 karakter digunakan.
Ini menghasilkan iterasi 20 25, di atas yang asli 12. Selain itu ia menyimpan 2 karakter dengan menggunakan int()
alih-alih floor()
yang diizinkan untuk x()
tumpukan tambahan . Jika spasi setelah lambda dapat dihapus (saya tidak dapat memeriksa saat ini) maka 5 y()
dapat ditambahkan. Mungkin!
Jika ada cara untuk melewatkan from math
impor dengan menggunakan nama yang sepenuhnya memenuhi syarat (mis. x=lambda i: math.log(i+1))
), Itu akan menyimpan lebih banyak karakter dan memungkinkan setumpuk lagi x()
tetapi saya tidak tahu apakah Python mendukung hal-hal seperti itu (saya curiga tidak). Selesai!
Ini pada dasarnya adalah trik yang sama yang digunakan dalam posting blog XCKD dalam jumlah besar , namun biaya overhead dalam mendeklarasikan lambdas menghalangi tumpukan ketiga:
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()))))
Ini adalah rekursi sekecil mungkin dengan 3 lambda yang melebihi tinggi tumpukan yang dihitung dari 2 lambdas (mengurangi setiap lambda menjadi dua panggilan menurunkan tinggi tumpukan menjadi 18, di bawah dari versi 2-lambda), tetapi sayangnya membutuhkan 110 karakter.