57 lines
1.4 KiB
Idris
57 lines
1.4 KiB
Idris
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
|