56 lines
1.5 KiB
Haskell
56 lines
1.5 KiB
Haskell
module Main where
|
|
|
|
import Debug.Trace
|
|
import System.Environment (getArgs)
|
|
|
|
main :: IO ()
|
|
main = do
|
|
input <- readFile . head =<< getArgs
|
|
print $ part1 input
|
|
print $ part2 input
|
|
|
|
part1 :: String -> Int
|
|
part1 = sum . filter invalid . concat . map ids . map parse . splitOn ','
|
|
|
|
splitOn :: (Eq a) => a -> [a] -> [[a]]
|
|
splitOn delim xs = case dropWhile (== delim) xs of
|
|
[] -> []
|
|
s' -> xs' : splitOn delim s''
|
|
where
|
|
(xs', s'') = break (== delim) s'
|
|
|
|
parse :: String -> (Int, Int)
|
|
parse = group . map read . splitOn '-'
|
|
where
|
|
group :: (Show a) => [a] -> (a, a)
|
|
group (x : y : []) = (x, y)
|
|
group x = error $ "group: " ++ show x ++ "is not two elements"
|
|
|
|
ids :: (Int, Int) -> [Int]
|
|
ids (start, end) = [start .. end]
|
|
|
|
invalid :: Int -> Bool
|
|
invalid i =
|
|
let s = show i
|
|
len = length s
|
|
half = take (len `div` 2) s
|
|
in s == half ++ half
|
|
|
|
part2 :: String -> Int
|
|
part2 = sum . filter invalid2 . concat . map ids . map parse . splitOn ','
|
|
|
|
invalid2 :: Int -> Bool
|
|
invalid2 i =
|
|
let s = show i
|
|
len = length s
|
|
facs = factors len
|
|
in or [(repeatN (len `div` n) $ take n s) == s | n <- facs]
|
|
|
|
-- needs to get the primes instead of all factors
|
|
factors :: Int -> [Int]
|
|
factors i = filter ((== 0) . (mod i)) [1 .. i `div` 2]
|
|
|
|
repeatN :: Int -> [a] -> [a]
|
|
repeatN i = concat . replicate i
|
|
|
|
testInput = "11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124"
|