1
0
Fork 0
universal-calculator/src/3n+1/collatzChainPost.lhs

81 lines
2.5 KiB
Plaintext

= 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
<https://youtu.be/094y1Z2wpJg>
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)