我試圖爲Project Euler的問題14編寫一個解決方案。我最快的 - 不是下面的 - 跑了58秒左右。我發現使用谷歌最快看上去或多或少是這樣的:試圖找到更快的Erlang項目#14的解決方案
%% ets:delete(collatz) (from shell) deletes the table.
-module(euler) .
-export([problem_14/1]) .
collatz(X) ->
case ets:lookup(collatz, X) of
[{X, Val}] -> Val ;
[] -> case X rem 2 == 0 of
true ->
ets:insert(collatz, {X, Val = 1+collatz(X div 2)}) ,
Val ;
false ->
ets:insert(collatz, {X, Val = 1+collatz(3*X+1)}) ,
Val
end
end .
%% takes 10 seconds for N=1000000 on my netbook after "ets:delete(collatz)".
problem_14(N) ->
case ets:info(collatz) of
undefined ->
ets:new(collatz, [public, named_table]) ,
ets:insert(collatz,{1,1}) ;
_ -> ok
end ,
lists:max([ {collatz(X), X} || X <- lists:seq(1,N) ]) .
但它仍然需要10.5秒用空表。我發現C++中速度最快的解決方案僅需0.18秒,速度提高了58倍。所以我猜即使Erlang不是爲了這樣的東西而編寫的,也可以編寫更好的代碼。有人可能知道我可以嘗試獲得一些速度嗎?
雖然有1000000個整數,但沒有必要全部計算爲1。經常出現一些「路徑」。例如,13和80具有最相同的步驟。 – halfelf
@halfelf,代碼中提出的問題是用於記憶的'ets'表,所以「路徑」的相同部分不會計算兩次。 – stemm
Erlang使用任意精度整數,不是嗎?如果有的話,使用本機64位整數類型可能會大大加快速度。還有一點,你在查找表(1168611)中輸入了很多數字'> 1000000'。他們中只有46675人再次擡頭看。只記憶'n <= 1000000'的值可能會更快(但這取決於實施記憶的方式)。可能使用可變數組記憶 - 如果可用的話 - 也是一個勝利(這在Haskell中是一個巨大的勝利)。最後,嘗試使用掩碼和移位而不是'rem 2'和'div 2'來提高速度。 –