2022/03/Main.idr

76 lines
1.9 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
-- Shared items across a collection of backpack
shared : List Backpack -> List Item
shared xs =
let combined = map (\(B left right) => left ++ right ) xs
in nub . intersectAll $ combined
-- Chunk a list
chunk : Nat -> List a -> List (List a)
chunk x [] = []
chunk x xs =
let head = take x xs
tail = chunk x . drop x $ xs
in head :: tail
main : IO ()
main =
do file <- readFile "input"
case file of
Right content =>
let backpacks = catMaybes . map parseBackpack . lines $ content
priorityTotals = sum . map (sum . map priority . duplicatedItems) $ backpacks
elves = chunk 3 backpacks
badges = map shared elves
badgeTotal = sum . map (sum . map priority) $ badges
in do putStr "part 1: "
printLn priorityTotals
putStr "part 2: "
printLn badgeTotal
Left err => printLn err