You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
38 lines
1.2 KiB
Haskell
38 lines
1.2 KiB
Haskell
import Data.List
|
|
|
|
|
|
main :: IO ()
|
|
main = do
|
|
input <- readFile "input"
|
|
putStrLn . formatOutput . both (sum . map length) . groups . map lines . dlfsplit $ input
|
|
|
|
|
|
formatOutput :: Show a => (a, a) -> String
|
|
formatOutput (part1,part2) = "Part 1: " ++ show part1 ++ "\nPart 2: " ++ show part2
|
|
|
|
-- Collect each group's answers
|
|
groups :: (Foldable t, Eq a) => [t [a]] -> ([[a]], [[a]])
|
|
groups [] = ([],[])
|
|
groups (g:gs) = (foldr1 union g : unions, foldr1 intersect g : intersections)
|
|
where (unions, intersections) = groups gs
|
|
|
|
-- Split a string into a list across all the double newlines in it
|
|
dlfsplit :: String -> [String]
|
|
dlfsplit str = a : case b of
|
|
[] -> []
|
|
b -> dlfsplit b
|
|
where (a,b) = dlfsplitonce str
|
|
|
|
-- Split a string into two across the first double newline found
|
|
dlfsplitonce :: String -> (String, String)
|
|
dlfsplitonce [] = ([], [])
|
|
dlfsplitonce (ca:cb:rest)
|
|
| ca == '\n' && cb == '\n' = ([], rest)
|
|
| otherwise = (ca:before, after)
|
|
where (before, after) = dlfsplitonce (cb : rest)
|
|
dlfsplitonce c = (c, [])
|
|
|
|
-- Apply a function to both parts of a pair
|
|
both :: (a -> b) -> (a, a) -> (b, b)
|
|
both f (a,b) = (f a, f b)
|