import Debug.Trace traceOut :: Show a => a -> a traceOut x = traceShow x x addFirst :: [[a]] -> a -> [[a]] addFirst [] x = [[x]] addFirst (y:ys) x = ([x] ++ y) : ys split :: Eq a => [a] -> [a] -> [[a]] split _ [] = [] split delims (x:xs) | elem x delims = [[]] ++ split delims xs | otherwise = addFirst (split delims xs) x parseFile :: String -> [(Int, Int)] parseFile = map ((\(x,y) -> (read x, read (drop 1 y))) . break (=='-')) . split [','] factors :: Int -> [Int] factors 1 = [] factors 2 = [1] factors 3 = [1] factors 4 = [1,2] factors 5 = [1] factors 6 = [1,2,3] factors 7 = [1] factors 8 = [1,2,4] factors 9 = [1,3] factors 10 = [1,2,5] factors 11 = [1] factors 12 = [1,2,3,4,6] isRepeatN :: Int -> Int -> Bool isRepeatN n x = (pow10 x > 0) && ((x `mod` divisor) == 0) && (x `div` divisor < 10^n) where pow10 = (`div` n) . digits divisor = sum $ take (pow10 x) $ iterate (* 10^n) 1 digits = (+1) . floor . logBase 10 . fromInteger . toInteger isRepeat2 x = ((digits x) `mod` 2 == 0) && (isRepeatN ((digits x) `div` 2) x) isRepeat x = foldl (||) False $ map (`isRepeatN` x) (factors $ digits x) solve1 :: [(Int, Int)] -> Int solve1 = sum . map (sum) . map (filter isRepeat2) . map (\(a, b) -> [a..b]) solve2 :: [(Int, Int)] -> Int solve2 = sum . map (sum) . map (filter isRepeat) . map (\(a, b) -> [a..b]) main = do fileinp <- readFile "input.txt" let input = parseFile fileinp let solved1 = solve1 input let solved2 = solve2 input print solved1 print solved2