今天,我正在玩Haskell中的Collatz序列...
这是我的代码:
collatzLength :: Int -> Integer -> Int
collatzLength count 1 = count
collatzLength count n = collatzLength (count+1) $ if n `mod` 2 == 0 then n `div` 2 else 3*n+1
main =
print (collatzLength 1 (10^10000 + 1))
我想做的是在[1,3]上无限迭代。每次找到新的最大Collatz长度时,我想在屏幕上显示它,然后继续。我不知道如何在Haskell中做到这一点,因为我必须在某处保持并更新最大长度值。
答案 0 :(得分:2)
使用main = print $ map (collatzLength 1) [1,3..]
和无限范围
main :: IO ()
main = loop 1
loop :: Int -> IO ()
loop n = do
print (collatzLength 1 n)
loop (n+2)
或使用显式递归
loop :: Int -> Int -> IO ()
loop n prevMax = do
let m = collatzLength 1 n
putStrLn $ "collatzLength 1 " ++ show n ++ " = " ++ show m
let nextMax = max prevMax m
putStrLn $ "current maximum = " ++ show nextMax
loop (n+2) nextMax
后一种方法可以让你对循环有更好的控制。
请注意,每个循环都会从头开始计算序列号,而不会利用以前计算的结果。为了更有效的方法,请查找memoization(不要与" memorization"混淆)。这些技术使程序能够记住"先前计算的递归调用的结果,以便新调用不必重新计算相同的值。
如果要保留所有返回值的最大值,可以使用
-- Assumes a list of positive numbers.
-- Returns the list of those elements which are larger than all the
-- previous ones.
highPoints :: [Int] -> [Int]
highPoints xs = go 0 xs
where
go :: Int -> [Int] -> [Int]
go _ [] = []
go currentMax (n:ns) | n > currentMax = n : go n ns
| otherwise = go currentMax ns
main :: IO ()
main = do
let collatzSequence :: [Int]
collatzSequence = map (collatzLength 1) [1,3..]
print (highPoints collatzSequence)
但我不想打印所有结果。只有长度高于"当前"最大长度。
然后,生成一个列表"更高"分:
$("ul a.toggle").click(function() {
$(this).next("ul").slideToggle();
});