Experimenting efficiency of Haskell
This commit is contained in:
parent
b79d41a7d1
commit
ee8a5460c3
3 changed files with 108 additions and 0 deletions
39
014.c
Normal file
39
014.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int longest = 0;
|
||||
int terms = 0;
|
||||
int i;
|
||||
unsigned long j;
|
||||
int this_terms;
|
||||
|
||||
for (i = 1; i <= 1000000; i++)
|
||||
{
|
||||
j = i;
|
||||
this_terms = 1;
|
||||
|
||||
while (j != 1)
|
||||
{
|
||||
this_terms++;
|
||||
|
||||
if (this_terms > terms)
|
||||
{
|
||||
terms = this_terms;
|
||||
longest = i;
|
||||
}
|
||||
|
||||
if (j % 2 == 0)
|
||||
{
|
||||
j = j / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
j = 3 * j + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("longest: %d (%d)\n", longest, terms);
|
||||
return 0;
|
||||
}
|
39
014.hs
Normal file
39
014.hs
Normal file
|
@ -0,0 +1,39 @@
|
|||
import Data.List
|
||||
type YInt = Int
|
||||
|
||||
collatz :: YInt -> YInt
|
||||
collatz n = if n<0 then 1 else if even n then n `quot` 2 else 3*n+1
|
||||
|
||||
-- The l `seq` is necessary to not be lazy (non-strict)
|
||||
-- And not to fill the stack
|
||||
lencollatz' :: YInt -> YInt -> YInt
|
||||
lencollatz' l 1 = l
|
||||
lencollatz' l n = l `seq` lencollatz' (l+1) (collatz n)
|
||||
|
||||
lencollatz = lencollatz' 0
|
||||
|
||||
-- The j `seq` is necessary to not be lazy (non-strict)
|
||||
-- And not to fill the stack
|
||||
maximalIndex :: (YInt,YInt) -> YInt -> [YInt] -> (YInt,YInt)
|
||||
maximalIndex (m,i) j [] = (m,i)
|
||||
maximalIndex (m,i) j (x:xs) = j `seq` maximalIndex res (j+1) xs
|
||||
where res = if x>m then (x,j) else (m,i)
|
||||
|
||||
showCollatz :: YInt -> String
|
||||
showCollatz 1 = "1"
|
||||
showCollatz n = show n ++ " → " ++ showCollatz ( collatz n )
|
||||
|
||||
pure (Just x) = x
|
||||
|
||||
main = do
|
||||
putStrLn $ "max len: " ++ show m
|
||||
putStrLn $ "max value: " ++ show i
|
||||
-- print mrec
|
||||
-- print irec
|
||||
-- putStrLn $ showCollatz $ toInteger i
|
||||
where
|
||||
array = map lencollatz [1..1000000]
|
||||
m = maximum array
|
||||
i = 1 + pure (elemIndex m array)
|
||||
(mrec,irec) = maximalIndex (0,0) 1 array
|
||||
|
30
014c.hs
Normal file
30
014c.hs
Normal file
|
@ -0,0 +1,30 @@
|
|||
{-# LANGUAGE BangPatterns #-}
|
||||
module Main (main) where
|
||||
|
||||
import Data.Bits
|
||||
|
||||
main :: IO ()
|
||||
main = putStrLn $ "longest: " ++ show longest ++ " (" ++ show terms ++ ")"
|
||||
where IP longest terms = euler14
|
||||
|
||||
data IntPair = IP {-# UNPACK #-} !Int {-# UNPACK #-} !Int
|
||||
|
||||
euler14 :: IntPair
|
||||
euler14 = go 1 0 0
|
||||
where
|
||||
go :: Int -> Int -> Int -> IntPair
|
||||
go i !longest !terms | i <= 1000000 = while i 1 longest terms
|
||||
| otherwise = IP longest terms
|
||||
where
|
||||
while :: Int -> Int -> Int -> Int -> IntPair
|
||||
while 1 !_ !longest !terms = go (i+1) longest terms
|
||||
while j thisTerms longest terms =
|
||||
let thisTerms' = thisTerms + 1
|
||||
IP terms' longest' = if thisTerms > terms
|
||||
then IP thisTerms i
|
||||
else IP terms longest
|
||||
j' = if j<0 then 1 else
|
||||
if j .&. 1 == 0
|
||||
then j `quot` 2
|
||||
else 3 * j + 1
|
||||
in while j' thisTerms' longest' terms'
|
Loading…
Reference in a new issue