1
0
Fork 0
projecteuler/74.hs

40 lines
1.4 KiB
Haskell
Raw Normal View History

2017-07-05 00:39:44 +00:00
import Data.Char (digitToInt)
2017-07-10 21:39:39 +00:00
import qualified Data.Map as Map
2017-07-05 00:39:44 +00:00
digitFactorial :: Integer -> Integer
digitFactorial n = case n of
0 -> 1
1 -> 1
2 -> 2
3 -> 6
4 -> 24
5 -> 120
6 -> 720
7 -> 5040
8 -> 40320
9 -> 362880
2017-07-10 21:39:39 +00:00
type ChainMap = Map.Map Integer Integer
initialMap :: ChainMap
initialMap = Map.fromList [(169, 3), (363601, 3), (1454, 3),
(871, 2), (872, 2), (45361, 2), (45362, 2),
(1, 1), (2, 1), (145, 1)]
2017-07-05 00:39:44 +00:00
sumOfFactorialOfDigits :: Integer -> Integer
sumOfFactorialOfDigits n = sum $ map (digitFactorial . fromIntegral . digitToInt) $ show n
2017-07-10 21:39:39 +00:00
getChainLength :: Integer -> ChainMap -> (Integer, ChainMap)
getChainLength n chainMap = case Map.lookup n chainMap of
Just length -> (length, chainMap)
Nothing -> let next = sumOfFactorialOfDigits n
(nextLength, nextChainMap) = getChainLength next chainMap
length = nextLength + 1
in (length, Map.insert n length nextChainMap)
2017-07-05 00:39:44 +00:00
2017-07-10 21:39:39 +00:00
numOfLoops :: Integer -> Integer -> (Integer, ChainMap)
numOfLoops bound length = foldr (\n (num, oldMap) -> let (chainLength, newMap) = getChainLength n oldMap
in (num + if chainLength == length then 1 else 0, newMap)) (0, initialMap) [3..bound]
2017-07-05 00:39:44 +00:00
2017-07-10 21:39:39 +00:00
main = print $ let (length, sizeMap) = numOfLoops 10000 60
in length