-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtask2.hs
More file actions
46 lines (38 loc) · 1.32 KB
/
task2.hs
File metadata and controls
46 lines (38 loc) · 1.32 KB
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
-- https://lotz84.github.io/haskellbyexample/ex/string-functions
split :: String -> Char -> [String]
split "" _ = []
split xs c = let (ys, zs) = break (== c) xs
in if null zs then [ys] else ys : split (tail zs) c
toInterval :: String -> (Int, Int)
toInterval input = (read start, read end)
where [start, end] = split input '-'
parse :: String -> [(Int, Int)]
parse input = map toInterval (split input ',')
digits :: Int -> Int
digits n = floor (logBase 10 (fromIntegral n)) + 1
part :: Int -> Int -> Int -> Int
part n index length = (n `mod` top) `div` bottom
where
d = digits n
top = 10^(d - index)
bottom = 10^(d - index - length)
repeatingPattern :: Int -> Int -> Bool
repeatingPattern n lambda = d `mod` lambda == 0 && allEqual && firstPart > 0
where
d = digits n
repetitions = d `div` lambda
parts = [part n (i * lambda) lambda | i <- [0..repetitions-1]]
firstPart = head parts
allEqual = all (== firstPart) parts
isInvalid :: Int -> Bool
isInvalid n = any (repeatingPattern n) [1..d `div` 2]
where
d = digits n
invalids :: (Int, Int) -> Int
invalids (start, end) = sum [n | n <- [start..end], isInvalid n]
main :: IO ()
main = do
input <- readFile "input.txt"
let intervals = parse input
result = sum [invalids interval | interval <- intervals]
print result