2022/03/Main.idr

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