Created
September 27, 2012 14:03
-
-
Save Javran/3794183 to your computer and use it in GitHub Desktop.
not-a-well-optimized solution for project euler p-14
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- complied with: ghc --make problem-14 -rtsopts | |
-- run with: ./problem-14 +RTS -K20000000 -RTS | |
-- time elapsed: 32.592s | |
import qualified Data.Set as S | |
-- (set, (x,value)) | |
-- set: a set to keep numbers that has been calculated | |
-- x: a number | |
-- value: the length that corresponding number, namely x has | |
type CalcStatus = ( S.Set Integer, (Integer, Int) ) | |
collatz :: Integer -> Integer | |
collatz n = if odd n | |
then 3 * n + 1 | |
else n `div` 2 | |
generateCollatzList :: Integer -> [Integer] | |
generateCollatzList 1 = [1] | |
generateCollatzList x = x : (generateCollatzList $ collatz x) | |
-- returns (x, value) in which value should be the biggest one in terms of its collatz length | |
solve :: Integer -> CalcStatus | |
solve limit = foldl doCalc (S.fromList [1], (1, 1) ) $ reverse [1 .. limit] where | |
doCalc :: CalcStatus -> Integer -> CalcStatus | |
doCalc (s, (maxX, maxLen)) i = result | |
where | |
result = if (newList == []) | |
then | |
-- there is nothing new | |
(s, (maxX, maxLen)) | |
else | |
-- insert new elements into the list and update (x, value) if it is possible | |
(newS, (newMaxX, newMaxLen)) | |
newGenList = generateCollatzList i | |
newList = takeWhile (\e -> not $ e `S.member` s) newGenList | |
newS = foldr S.insert s newList | |
(newMaxX, newMaxLen) = if ( length newGenList > maxLen ) | |
then (i, length newGenList) | |
else (maxX, maxLen) | |
main = print $ snd $ solve 1000000 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment