我的目標是編寫一個函數來計算低於特定數字'n'的最大Collatz數。 (對於那些熟悉的人來說,這是個項目歐拉問題。)Haskell初學者:「沒有......因...而產生的錯誤」錯誤
某些上下文:給定整數的Collatz數等於該整數的Collatz序列的長度。一個整數的Collatz序列計算如下:序列中的第一個數字(「n0」)是該整數本身;如果n0是偶數,序列中的下一個數字(「n1」)等於n/2;如果n0是奇數,那麼n1等於3 * n0 + 1。我們繼續遞歸地擴展序列直到我們到達1,此時序列結束。例如,5的collatz序列是:{5,16,8,4,2,1}(因爲16 = 3 * 5 + 1,8 = 16/2,4 = 8/2,...)
我想寫一個函數(「maxCollatzUnder」),當它傳遞一個整數「m」時,返回具有最長Collatz序列(即最大Collatz數)的整數(小於或等於m) 。例如,maxCollatz 20(即,下面的哪個整數(包括)20具有最長的拼貼序列?)應該返回19(數字19具有長度爲21的Collatz序列:[19,58,29,88,44,22, 11,34,17,52,26,13,40,20,10,5,16,8,4,2,1])。
在下面的代碼中,「collatz」和「collatzHelper」函數編譯並正確運行。我在使用「maxCollatzUnder」功能時遇到了問題。該函數旨在(1)爲1到m範圍內的每個整數x(其中m是函數參數)創建一個2元組(x,y)的列表,其中y表示整數x的Collatz數,然後II)瀏覽列表中爲最高在Collatz數(即,y),並返回其相關的整數(即X)
maxCollatzUnder n = foldl(\acc (i,j) -> if j > acc then i else acc) 0
(zip [1..n] (map collatzLength [1..n]))
where collatzLength n = length . collatz $ n
collatz n = map truncate $ collatzHelper n
collatzHelper 0 = [0]
collatzHelper 1 = [1]
collatzHelper n
| (truncate n) `mod` 2 == 0 = [n] ++ collatzHelper (n/2)
| otherwise = [n] ++ collatzHelper (3*n+1)
我收到以下錯誤,當我(嘗試)編制。
*Main> :l PE14Collatz.hs
[1 of 1] Compiling Main (PE14Collatz.hs, interpreted)
PE14Collatz.hs:7:89:
No instance for (RealFrac Int)
arising from a use of `collatzLength'
In the first argument of `map', namely `collatzLength'
In the second argument of `zip', namely
`(map collatzLength [1 .. n])'
In the third argument of `foldl', namely
`(zip [1 .. n] (map collatzLength [1 .. n]))'
Failed, modules loaded: none.
有什麼奇怪的是,代碼編譯,如果我改變「maxCollatzUnder」下面的代碼(見下文)運行正常。唯一的變化是,在下面的版本中,摺疊函數返回「j」(即,最大Collatz數)而不是「i」(即,產生最大Collatz數的整數)。
maxCollatzUnder n = foldl(\acc (i,j) -> if j > acc then j else acc) 0
(zip [1..n] (map collatzLength [1..n]))
where collatzLength n = length . collatz $ n
對更高效/優雅的方法的建議是受歡迎的,儘管我仍然有興趣瞭解這個錯誤的原因。
你認爲這些函數的類型是什麼?例如,「collatz」的類型應該是什麼? – bheklilr 2014-10-02 02:16:52