-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprob35.hs
41 lines (31 loc) · 1.03 KB
/
prob35.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import Timer
import Utils
import Maths
import qualified Data.Map as M
import qualified Data.Set as S
import Data.List
main = do
time $ length (circular 999999)
circular n = M.foldWithKey (\n isP acc -> if isP then n:acc else acc) [] (cycleMap n)
cycleMap n = foldl' (\mp n -> insrt n mp) M.empty [2..n]
cycles digits = map (toNumber) (shift (length digits) digits)
insrt n mp
| M.member n mp = mp
insrt n mp
| hasEven = mp
| hasFive = mp
| otherwise = insrt' (cycles digits) mp
where digits = toDigits n
multiDigits = (length digits) > 1
hasEven = multiDigits && any even digits
hasFive = multiDigits && 5 `elem` digits
insrt' cycs mp = M.union mp (M.fromList circPairs)
where isCircular = (dropWhile isPrime' cycs) == []
circPairs = foldl' (\acc x -> (x, isCircular):acc) [] cycs
isPrime' n = S.member n pSet
pSet = S.fromList $ primesToN 999999
shift _ [] = []
shift _ [x] = [[x]]
shift 0 xs = []
shift n (x:xs) = [shifted] ++ (shift (n-1) shifted)
where shifted = xs ++ [x]