1
0
Fork 0

Rebase laster some tests

main
Bill Ewanick 2024-12-21 13:30:58 -05:00
parent d54b9f9812
commit ea4d0e8580
3 changed files with 97 additions and 22 deletions

View File

@ -3,29 +3,17 @@ The Simplest Math Problem No One Can Solve - Collatz Conjecture
https://youtu.be/094y1Z2wpJg https://youtu.be/094y1Z2wpJg
-} -}
import Control.Parallel.Strategies (parMap, rdeepseq, rpar) import Data.Set (fromList)
import Data.Set (fromList) import Debug.Trace (trace)
import Debug.Trace (trace)
main :: IO () main :: IO ()
main = do main = do
let results = let results = map f [10^1_000..10^1_000+100] :: [Integer]
parMap rdeepseq f [10^100_000..10^100_000+100] :: [Integer]
print (fromList results) print (fromList results)
-- main = print $ fromList $ dxs
-- main = print $ fromList $ take 300 $ map f [2^100_000..]
-- fromList [100001,717859]
-- main = print $ fromList $ take 3 $ map f [2^310997..]
-- main = print $ f $ 2^310997 + 2
lst :: [Integer] lst :: [Integer]
lst = take 300 [2^100_000..] lst = take 300 [2^100_000..]
dxs :: [Integer]
dxs = parMap rpar f lst
f :: Integer -> Integer f :: Integer -> Integer
f n = s 1 n f n = s 1 n
where where
@ -71,3 +59,5 @@ cc n = cc' [] n
| even n = cc' acc' (n `div` 2) | even n = cc' acc' (n `div` 2)
| odd n = cc' acc' (3*n + 1) | odd n = cc' acc' (3*n + 1)
where acc' = acc <> [n] where acc' = acc <> [n]
x = map (length . cc) [2^1_000+10..]

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,81 @@
= 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)