Rebase laster some tests
parent
d54b9f9812
commit
ea4d0e8580
|
@ -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
|
@ -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)
|
Loading…
Reference in New Issue