54 lines
1.3 KiB
Haskell
54 lines
1.3 KiB
Haskell
|
module Day1 where
|
||
|
|
||
|
import Data.List
|
||
|
import ParseLib
|
||
|
import Util
|
||
|
|
||
|
main :: IO ()
|
||
|
main = do
|
||
|
example <- getFileContents "app/Day1-example.txt"
|
||
|
input <- getFileContents "app/Day1-input.txt"
|
||
|
|
||
|
putStrLn "Part 1"
|
||
|
putStrLn $ "Example: " ++ show (part1 example)
|
||
|
putStrLn $ "Input: " ++ show (part1 input)
|
||
|
putStrLn ""
|
||
|
putStrLn "Part 2"
|
||
|
putStrLn $ "Example: " ++ show (part2 example)
|
||
|
putStrLn $ "Input: " ++ show (part2 input)
|
||
|
|
||
|
part1 :: String -> Int
|
||
|
part1 input = sum
|
||
|
$ fmap (unwrap . foldMap Difference)
|
||
|
$ getPairwise
|
||
|
$ traverse (Pairwise . sort)
|
||
|
$ sequenceA
|
||
|
$ tryparse lexer input
|
||
|
|
||
|
part2 :: String -> Int
|
||
|
part2 input = sum $ fmap (\x -> x * count list2 x) list1
|
||
|
where Line list1 list2 = sequenceA (tryparse lexer input)
|
||
|
|
||
|
|
||
|
data Line a = Line a a deriving (Show)
|
||
|
|
||
|
-- Parser code
|
||
|
|
||
|
lexer :: Parser Char [Line Int]
|
||
|
lexer = greedy parseLine
|
||
|
|
||
|
parseLine :: Parser Char (Line Int)
|
||
|
parseLine = Line <$$> natural <$* token " " <$*> natural <$* token "\n"
|
||
|
|
||
|
instance Functor Line where
|
||
|
fmap f (Line x y) = Line (f x) (f y)
|
||
|
|
||
|
instance Applicative Line where
|
||
|
pure x = Line x x
|
||
|
(<*>) (Line fx fy) (Line x y) = Line (fx x) (fy y)
|
||
|
|
||
|
instance Foldable Line where
|
||
|
foldMap f (Line x y) = f x `mappend` f y
|
||
|
|
||
|
instance Traversable Line where
|
||
|
traverse f (Line x y) = liftA2 Line (f x) (f y)
|