6 | parseLine : String -> Maybe (Integer, Integer)
8 | let parts = filter (not . null) . map trim . forget . split (== ' ') $
str
10 | [first, second] => do
11 | first <- parseInteger first
12 | second <- parseInteger second
13 | Just (first, second)
16 | parseInput : String -> Maybe (List Integer, List Integer)
18 | map unzip . traverse parseLine . lines
20 | totalDistance : List Integer -> List Integer -> Integer
21 | totalDistance xs ys =
22 | sum . map distance $
zip (sort xs) (sort ys)
24 | distance : (Integer, Integer) -> Integer
31 | part1 : String -> IO (String, (List Integer, List Integer))
33 | case parseInput str of
35 | putStrLn "Failed to parse input string."
37 | Just (xs, ys) => pure (show $
totalDistance xs ys, (xs, ys))
39 | similarityScore : List Integer -> List Integer -> Integer
40 | similarityScore xs ys =
41 | sum . map (\x => x * natToInteger (count (== x) ys)) $
xs
44 | part2 : (List Integer, List Integer) -> String -> IO String
46 | pure . show $
similarityScore xs ys