Advent of Code solutions https://adventofcode.com
You can not 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.2KB

  1. import Data.List
  2. main :: IO ()
  3. main = do
  4. input <- readFile "input"
  5. putStrLn . formatOutput . both (sum . map length) . groups . map lines . dlfsplit $ input
  6. formatOutput :: Show a => (a, a) -> String
  7. formatOutput (part1,part2) = "Part 1: " ++ show part1 ++ "\nPart 2: " ++ show part2
  8. -- Collect each group's answers
  9. groups :: (Foldable t, Eq a) => [t [a]] -> ([[a]], [[a]])
  10. groups [] = ([],[])
  11. groups (g:gs) = (foldr1 union g : unions, foldr1 intersect g : intersections)
  12. where (unions, intersections) = groups gs
  13. -- Split a string into a list across all the double newlines in it
  14. dlfsplit :: String -> [String]
  15. dlfsplit str = a : case b of
  16. [] -> []
  17. b -> dlfsplit b
  18. where (a,b) = dlfsplitonce str
  19. -- Split a string into two across the first double newline found
  20. dlfsplitonce :: String -> (String, String)
  21. dlfsplitonce [] = ([], [])
  22. dlfsplitonce (ca:cb:rest)
  23. | ca == '\n' && cb == '\n' = ([], rest)
  24. | otherwise = (ca:before, after)
  25. where (before, after) = dlfsplitonce (cb : rest)
  26. dlfsplitonce c = (c, [])
  27. -- Apply a function to both parts of a pair
  28. both :: (a -> b) -> (a, a) -> (b, b)
  29. both f (a,b) = (f a, f b)