= Collatz Chains in Haskell == Title header This is a literate haskell blog post. You can load and run this code! The Simplest Math Problem No One Can Solve - Collatz Conjecture Why do we want to do this? > collatzStep :: Integer -> Integer > collatzStep n > | even n = n `div` 2 > | odd n = 3 * n + 1 With this, we can iterate over it. > collatzStep' :: Integer -> Integer > collatzStep' n > | n == 1 = error "done" > | even n = n `div` 2 > | odd n = 3 * n + 1 > result :: [Integer] > result = iterate collatzStep' 5 collatz collect generate the collatz sequence and return it > cc :: Integer -> [Integer] > cc n = cc' [] n > where > cc' :: [Integer] -> Integer -> [Integer] > cc' acc n > | n == 1 = acc <> [1] > | n == 0 = acc <> [0] > | n == (-1) = acc <> [-1] > | n == (-5) = acc <> [-5] > | n == (-17) = acc <> [-17] > | even n = cc' acc' (n `div` 2) > | odd n = cc' acc' (3*n + 1) > where acc' = acc <> [n] > a :: [Integer] > a = reverse $ cc $ 2^1_000+1 > b :: [Integer] > b = reverse $ cc $ 2^1_000+2 > comparingChains :: [Bool] > comparingChains = zipWith (==) a b Now if we collect the chain lengths of large numbers we see something slightly horrifying: > x = map (length . cc) [2^1_000+10..] This prints us the list of lengths of the chain as: [7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7430,7249,7249,7249,7249,7249,7249,7249,7249,7249,7430,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7430,7430,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7430,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7430,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7430,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249,7249...] λ> cc 13 [13,40,20,10,5,16,8,4,2,1] λ> cc 12 [12,6,3,10,5,16,8,4,2,1] Now this makes sense with small numbers. But I find it weird with large numbers. > f :: Integer -> Integer > f n = s 1 n > where > s :: Integer -> Integer -> Integer > s i n > | n == 1 = i > | n == 0 = i > | n == (-1) = i > | n == (-5) = i > | n == (-17) = i > | even n = s (succ i) (n `div` 2) > | odd n = s (succ i) (3 * n + 1)