1 import qualified Data.HashMap.Strict as M
2 import Data.List (foldl') -- import the strict fold
3 import Data.List.Split (splitOn)
5 -- a key-value store for recording how often each name is seen
6 type NameCount = M.HashMap String Int
10 -- text <- readFile "data/small_invites.txt"
11 text <- readFile "data/00-invites.txt"
15 -- use `words` here as I don't need to worry about the comma delimiters
16 part1 :: String -> Int
17 part1 = maximum . map (length . words) . lines
19 part2 :: String -> Int
20 part2 inviteText = M.size popular
21 where -- split names on the delimieter, use `concatMap` to give just one long list
22 invites = concatMap (splitOn ", ") $ lines inviteText
24 invited = nameCounts invites
25 -- popular are those mentioned more than once
26 popular = M.filter (> 1) invited
29 -- count how many times each name appears.
30 -- It's a fold over the list of names, creating the name count HashMap.
31 -- As each name is taken from the list, we find how many times we've seen it
32 -- before, add one to it, then update the HashMap with the new count.
33 nameCounts :: [String] -> NameCount
34 nameCounts names = foldl' includeName M.empty names
35 where includeName nc name = M.insert name (1 + count name nc) nc
36 -- a default count of 0 for each name
37 count name = M.lookupDefault 0 name