İşte CPU'nun pahasına sabit bellekle çalışan bir cevap. Bu, asıl soru bağlamında iyi bir cevap değildir (yani bir röportaj sırasında cevap). Ancak röportaj 24 saat sürüyorsa, o kadar da kötü değil. ;)
Fikir şu ki, eğer geçerli bir cevap olan n varsa, o zaman sıradaki bir sonraki iki kuvvetin n katı, 5'in gücüne bölünür. Ya da n kere 5'in gücüne bölünür. ikisinin gücü. Eşit şekilde bölünmesi şartıyla. (... veya bölen 1 olabilir;) bu durumda sadece 2 veya 5 ile çarpıyorsunuz)
Örneğin, 625'ten 640'a gitmek için 5 ** 4/2 ** 7 ile çarpın. Veya daha genel olarak, 2 ** m * 5 ** n
bir kişinin pozitif ve birinin negatif veya sıfır olduğu bazı m, n için bir değerle çarpın . çarpan sayıyı eşit olarak böler.
Şimdi, zor kısmı çarpanı bulmak. Ama biliyoruz ki a) bölen sayıyı eşit olarak bölmelidir, b) çarpan birden büyük olmalıdır (sayılar artmaya devam eder) ve c) 1'den büyük en düşük çarpanı seçersek (yani 1 <f <diğer tüm f'ler) ), bu durumda bir sonraki adımımız garanti edilir. Bundan sonraki adım en düşük adım olacaktır.
Kötü kısmı m, n değerini bulmaktır. Sadece log (n) olasılıkları vardır, çünkü vazgeçecek çok fazla 2 ya da 5 vardır, ama yuvarlak kapanışla başa çıkmak için özensiz bir yol olarak -1'den + 1'e bir faktör eklemek zorunda kaldım. Bu yüzden her adımı sadece O (log (n)) üzerinden yinelemeliyiz. Yani genel olarak O (n log (n)).
İyi haber şu ki, bir değer alıyor ve bir sonraki değeri buluyor, dizinin herhangi bir yerine başlayabilirsiniz. Yani 1 milyardan sonra bir sonrakini istiyorsanız, 2/5 veya 5 / 2'leri tekrarlayarak ve 1'den büyük en küçük çarpanı seçerek bulabilirsiniz.
(Piton)
MAX = 30
F = - math.log(2) / math.log(5)
def val(i, j):
return 2 ** i * 5 ** j
def best(i, j):
f = 100
m = 0
n = 0
max_i = (int)(math.log(val(i, j)) / math.log(2) + 1) if i + j else 1
#print((val(i, j), max_i, x))
for mm in range(-i, max_i + 1):
for rr in {-1, 0, 1}:
nn = (int)(mm * F + rr)
if nn < -j: continue
ff = val(mm, nn)
#print(' ' + str((ff, mm, nn, rr)))
if ff > 1 and ff < f:
f = ff
m = mm
n = nn
return m, n
def detSeq():
i = 0
j = 0
got = [val(i, j)]
while len(got) < MAX:
m, n = best(i, j)
i += m
j += n
got.append(val(i, j))
#print('* ' + str((val(i, j), m, n)))
#print('- ' + str((v, i, j)))
return got
Sıralanan liste çözümü tarafından üretilen ilk 10.000'e göre ürettiği ilk 10.000 sayısını doğruladım ve en azından o kadar çalışıyor.
BTW bir trilyondan sonra bir sonraki 1.024.000.000.000 gibi görünüyor.
...
Hm. best()
Adım adım genişlettiğim bir arama tablosu olarak davranarak O (n) performansını - değer (!) Başına O (1) - ve O (günlük n) bellek kullanımını elde edebilirim . Şu anda her seferinde yineleyerek bellek tasarrufu sağlıyor, ancak çok fazla hesaplama yapıyor. Bu ara değerleri - ve min değerleri listesini - tutarak, yinelenen çalışmayı önleyebilir ve çok hızlandırabilirim. Bununla birlikte, ara değerlerin listesi n ile birlikte büyüyecektir, dolayısıyla O (log n) belleği.