import Data.List import Data.List.Split import Data.Char (isDigit) main :: IO () main = do input <- readFile "5/riley.txt" let x = parse <$> lines input print $ f x print $ g x where f = solve . filter (not . diagonal) g = solve -- | Extract all the numbers from the given string parse :: String -> [Int] parse = map read . wordsBy (not . isDigit) -- | Determine if the given line is diagonal. diagonal :: [Int] -> Bool diagonal [ x1, y1, x2, y2 ] = x1 /= x2 && y1 /= y2 solve :: [[Int]] -> Int solve = length . filter ((>= 2) . length) . group . sort . (>>= range) -- | Transform a line to a list of points on that line. range :: [Int] -> [(Int,Int)] range [ x1, y1, x2, y2 ] | x1 == x2 = [ (x1,y) | y <- ys ] | y1 == y2 = [ (x,y1) | x <- xs ] | otherwise = zip xs ys where xs = gen x1 x2 ys = gen y1 y2 -- | Generate a list of numbers from `a` to `b`. gen :: Int -> Int -> [Int] gen a b | a > b = [ b .. a ] | otherwise = reverse [ a .. b ]