Saf Kötülük: 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 içindeki deyim uzunluğu 7 * dizesi oluşturur 10 10 10 10 10 10 8.57 şey ama oluşur lambda işlevine daha aramaların bir dizi inşa edecek, her biri benzer sonunda kadar bu şekilde devam uzunluğunda y
0. görünürde olur bu, aşağıdaki Eschew yöntemiyle aynı karmaşıklığa sahiptir, ancak eğer ve-veya-kontrol mantığına dayanmak yerine, sadece dev dizeleri bir araya getirir (ve net sonuç daha fazla yığın alıyor ... muhtemelen?).
y
Python hata vermeden sağlayabildiğim ve hesaplayabildiğim en büyük değer 2'dir, ki bu bir maksimum-yüzdürme girişini 1'e geri döndürmek için yeterlidir.
Uzunluğunda 7.625.597.484.987 bir dize sadece çok büyük: OverflowError: cannot fit 'long' into an index-sized integer
.
Durmalıyım.
Kaçınmak Math.log
: (sorunun) (10th-) kök giderek, skor: fonksiyonu etkili bir şekilde ayırt y = 1 den.
Matematik kitaplığını içe aktarmak bayt sayısını kısıtlıyor. Bunu kaldıralım ve log(x)
işlevi kabaca eşdeğer bir şeyle değiştirelim : x**.1
bu yaklaşık olarak aynı sayıda karaktere mal olur, ancak içe aktarılmasını gerektirmez. Her iki fonksiyon da girişe göre alt çizgi çıkışa sahiptir, ancak x 0.1 daha yavaş büyür . Bununla birlikte, çok fazla umursamıyoruz, yalnızca çok sayıda sayıyla aynı temel büyüme modeline sahip olmasına dikkat ediyoruz (örneğin x**.9
, aynı sayıda karakter tüketiyor , ancak daha hızlı büyüyor; aynı büyümeyi sergileyebilecek bir değerdir).
Şimdi, 16 karakterle ne yapmalı. Lambda fonksiyonumuzu Ackermann Sequence özelliklerine sahip olacak şekilde genişletmeye ne dersiniz? Çok sayıda bu cevap bu çözüme ilham verdi.
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
Bu z**z
bölüm, bu işlevi aklı başında girdilere yakın herhangi bir yerde çalıştırmamı engelliyor y
ve z
kullanabileceğim en büyük değerler 9 ve 3'tür ; bunun için en büyük kayan Python desteği için bile 1.0 değerini geri alırım (not: 1.0 sayısal olarak 6.77538853089e-05'ten büyük olduğunda, artan özyineleme seviyeleri, bu fonksiyonun çıktısını 1'e yaklaştırırken, 1'den büyük kalırken, önceki fonksiyon, 0'dan büyük kalırken değerleri 0'a yaklaştırdı; kayan nokta sayısı tüm önemli bitlerini kaybedecek kadar çok işlemle sonuçlanır .
Özgün lambda çağrısının 0 ve 2 özyineleme değerlerine sahip olacak şekilde yeniden yapılandırılması ...
>>>1.7976931348623157e+308
1.0000000071
Karşılaştırma, "1 dengeleme" yerine "0 dengeleme" ile yapılırsa, bu işlev 7.1e-9
kesinlikle daha küçük olana döner 6.7e-05
.
Gerçek programın temel özyinelemesi (z değeri) 10 10 10 10 10 1.97 , derinlemesine başlar tükenmez, 10 10 10 10 10 1.97 ile sıfırlanır (9'un başlangıç değeri yeterlidir), Oluşan toplam yinelemelerin sayısını doğru bir şekilde hesaplamayı bile bilmiyorum: Matematiksel bilgimin sonuna geldim. Benzer şekilde **n
üslerinden birinin ilk girdiden ikinciye taşınmasının z**z
özyineleme sayısını iyileştirip iyileştirmeyeceğini bilmiyorum (tersine çevirmek).
Daha fazla özyineleme ile daha da yavaşlayalım
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 bayttan fazla tasarruf sağlar int(n)
import math
, math.
1 bayttan tasarruf sağlarfrom math import*
a(...)
toplamda 8 bayt tasarruf m(m,...)
(y>0)*x
Bir bayt kaydeder overy>0and x
9**9**99
bayt sayısını 4 artırır ve yineleme derinliğini yaklaşık olarak eski derinliğin 2.8 * 10^x
olduğu yerde artırır x
(veya bir googolplex'e yaklaşan bir derinlik: 10 10 94 ).
9**9**9e9
bayt sayısını 5 artırır ve yineleme derinliğini artırır ... delice bir miktar. Özyineleme derinliği şimdi 10 10 10 9,93 , referans için bir googolplex 10 10 10 2'dir .
- lambda beyanı fazladan adım Özyinelemeyi artırır:
m(m(...))
için a(a(a(...)))
maliyetlerin 7 bayt
Yeni çıktı değeri (9 özyineleme derinliğinde):
>>>1.7976931348623157e+308
6.77538853089e-05
Özyineleme derinliği, aynı girdi değerlerini kullanan önceki sonuçlarla karşılaştırıldığında , bu sonucun kelimenin tam anlamıyla anlamsız olduğu noktaya patladı :
- Orijinal
log
25 kez aradı
- İlk gelişme 81 kez diyor
- Gerçek programı 1e99 çağırır 2 veya 10 yaklaşık 10 2.3 kat
- Bu sürüm 729 kez arar
- Gerçek bir program tarafından (9 çağırır 9 99 ) 3 ya da biraz az 10 10 95 kez).
Lambda Başlangıç, skor: ???
Lambdaları sevdiğini duydum, yani ...
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))
Hatta bu koşamam, ben sadece bile taşma yığını 99 özyinelemenin katmanları.
Eski yöntem (aşağıda) döndürür (dönüşümü bir tamsayıya atlayarak):
>>>1.7976931348623157e+308
0.0909072713593
Yeni yöntem, yalnızca 9 kat saldırı bildirimi kullanarak (tam googol yerine) döndürür :
>>>1.7976931348623157e+308
0.00196323936205
Bunun Ackerman dizisine benzer bir karmaşıklığa sahip olduğunu düşünüyorum, sadece büyük yerine küçük.
Ayrıca ETHproductions sayesinde mekanlarda 3-byte tasarruf sağladığımı fark etmedim.
Eski cevap:
Fonksiyon günlüğünün tamsayı kesmesi (i + 1) lambda'd lambdas kullanarak 20 25 kez (Python) yinelenmiştir.
PyRulez'in cevabı, ikinci bir lambda tanıtılarak ve istiflenerek sıkıştırılabilir:
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 kullanılmış.
Bu , orijinal 12'nin üzerinde 20 25'lik bir yinelemeye neden olur . Ayrıca , ek bir yığın için izin vermek int()
yerine, kullanarak 2 karakter kaydeder . Lambda'dan sonraki boşluklar kaldırılabiliyorsa (şu anda kontrol edemiyorum), o zaman 5. bir eklenebilir. Mümkün!floor()
x()
y()
from math
Tamamen nitelikli bir ad kullanarak (örneğin x=lambda i: math.log(i+1))
) içe aktarmayı atlamanın bir yolu varsa , bu daha fazla karakter kaydeder ve başka bir yığına izin verir, x()
ancak Python'un bu gibi şeyleri destekleyip desteklemediğini bilmiyorum (sanmıyorum). Bitti!
Bu esasen XCKD'nin blog yazısında büyük sayılarda kullanılan aynı numaradır , ancak lambda ilan etmenin ek yükü üçüncü bir yığını engellemektedir:
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()))))
Bu, 2 lambda'nın hesaplanan yığın yüksekliğini aşan 3 lambda ile mümkün olan en küçük özyinelemedir (herhangi bir lambdayı iki çağrıya düşürmek, yığın yüksekliğini 2 lambda sürümünün altına 18'in altına düşürür), ancak ne yazık ki 110 karakter gerektirir.