-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path014_longest_collatz_sequence.hs
47 lines (36 loc) · 1.37 KB
/
014_longest_collatz_sequence.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
42
43
44
45
46
47
import Data.Bits
collatzStep :: Int -> Int
collatzStep n
| even n = shiftR n 1
| otherwise = 3*n + 1
collatzChain :: Int -> [Int]
collatzChain n = collatzChain' n []
collatzChain' :: Int -> [Int] -> [Int]
collatzChain' n list
| n == 1 = 1 : list
| otherwise = collatzChain' (collatzStep n) (n : list)
collatzLength :: Int -> Int
collatzLength n = collatzLength' n 0
collatzLength' :: Int -> Int -> Int
collatzLength' n l
| n == 1 = l + 1
| otherwise = collatzLength' (collatzStep n) (l+1)
-- IntervallStart -> IntervallEnd -> (MaxN, MaxLength)
collatzMaxLength :: Int -> Int -> (Int, Int)
collatzMaxLength a b = collatzMaxLength' a b (0, 0)
-- Intervall -> (N, Length) -> (MaxN, MaxLength)
collatzMaxLength' :: Int -> Int -> (Int,Int) -> (Int,Int)
collatzMaxLength' i j maxl
| i == j = maxTouple (i, newLength) maxl
| otherwise = collatzMaxLength' (i+1) j (maxTouple (i, newLength) maxl)
where newLength = collatzLength' i 0
-- Min -> Max -> (tmpMaxN, tmpMaxLenght) -> (MaxN, MaxLength)
collatzMaxLength'' :: Int -> Int -> (Int, Int)
collatzMaxLength'' i j = foldr maxTouple (0, 0) (zip [i..j] (map collatzLength [i..j]))
-- compares two touples and returns the one with the bigger second entry
maxTouple :: (Ord b) => (a, b) -> (a, b) -> (a, b)
maxTouple t1 t2
| snd t1 > snd t2 = t1
| otherwise = t2
main::IO()
main = putStrLn $ show (collatzMaxLength'' 1 1000000)