import System.File.ReadWrite import Data.String import Data.List data Item = I Char Eq Item where (I a) == (I b) = a == b Show Item where show (I a) = show a -- Define the priority of item priority : Item -> Int priority (I char) = if isUpper char then ord char - 38 else ord char - 96 -- Spiit a list in half splitHalf : List a -> Maybe (List a, List a) splitHalf list = let len : Int len = cast $ length list halfLen : Int halfLen = div len 2 resultLen : Nat resultLen = cast halfLen in if len `mod` 2 == 0 then Just (take resultLen list, drop resultLen list) else Nothing data Backpack = B (List Item) (List Item) -- Parse a backpack from a string parseBackpack : String -> Maybe Backpack parseBackpack input = let items = map I . unpack $ input in do (left, right) <- splitHalf items Just (B left right) -- Get the duplicated items duplicatedItems : Backpack -> List Item duplicatedItems (B left right) = nub $ intersect left right main : IO () main = do file <- readFile "input" case file of Right content => let backpacks = catMaybes . map parseBackpack . lines $ content priorityTotals = foldl (+) 0 . map (foldl (+) 0 . map priority . duplicatedItems) $ backpacks in do putStr "part 1: " printLn priorityTotals Left err => printLn err