55 lines
1.5 KiB
Haskell
55 lines
1.5 KiB
Haskell
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
|