尤拉計劃686:2的冪

lt發表於2019-12-16

2^7=128是前導數字為“12”的第一個2的冪。

2^80是前導數字為“12”的第一個2的冪。

定義p(L,n)為以數字L開頭的第n小的2^j的j。

所以p(12,1)=7

而p(12,2)=80。

已知P(123,45)=12710。

求P(123,678910)。

數字很大,不可以直接計算,回憶起中學用對數來求大數位數的辦法。比如2^10的位數=10*lg(2)=10*0.3=3,所以科學計數法的結果就是a*10^3,於是想到用對數來解決,實際上也可能是唯一可行的辦法。

import time as tm
import math as m
ta=tm.time()
tb=ta
lg123=m.log(1.23)/m.log(10)
lg124=m.log(1.24)/m.log(10)
a=0
for i in range(1,12800000000):
 t= i*lg2-m.floor(i*lg2)
 if t >= lg123 and t<lg124:
  a=a+1
  if(a>=678910):
   tb=tm.time()
   print(a,i)
   print('time cost',tb-ta,'s')
   break

執行結果
678910 193060223
time cost 197.0109851360321 s

方法有點慢,觀察到相鄰的滿足條件的冪次差值有規律

冪次    差值
2515    196
2711    289
3000    196
3196    485
3681    196
3877    289 

大膽猜測,對所有數都是這個規律,於是有

import time as tm
import math as m
ta=tm.time()
tb=ta
lg2=m.log(2)/m.log(10)
lg123=m.log(1.23)/m.log(10)
lg124=m.log(1.24)/m.log(10)
a=0
i0=0
for i in range(1,128):
 t= i*lg2-m.floor(i*lg2)
 if t >= lg123 and t<lg124:
  a=a+1
  i0=i

while i0<12800000000:
 for gap in[196,289,485]:
  t= (i0+gap)*lg2-m.floor((i0+gap)*lg2)
  if t >= lg123 and t<lg124:
   a=a+1
   i0=i0+gap
   break
  if(a>=678910):
   tb=tm.time()
   print(a,i0)
   print('time cost',tb-ta,'s')
   exit
執行結果
678910 193060223
time cost 3.5182394981384277 s

時間約為1/50,符合預期。

至於這幾個魔術數,其實都是約等於1*10^n

In[1]:= 2.0^196

                  59
Out[1]= 1.00434 10

In[2]:= 2.0^289

                  86
Out[2]= 9.94646 10

In[3]:= 2.0^485

                 145
Out[3]= 9.9896 10

PE論壇上有人還發現196=14^2, 289=17^2,485=196+289

相關文章