X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;f=advent03%2FMain.hs;fp=advent03%2FMain.hs;h=409ca338c6cc396c83e41b9ab1be4b055582cf50;hb=4df30f4f37244271ea01f3e64c1fba6c36c20e94;hp=0000000000000000000000000000000000000000;hpb=ec5050108d9c636018dabb874aae6114ce59b5c2;p=advent-of-code-22.git diff --git a/advent03/Main.hs b/advent03/Main.hs new file mode 100644 index 0000000..409ca33 --- /dev/null +++ b/advent03/Main.hs @@ -0,0 +1,61 @@ +-- Writeup at https://work.njae.me.uk/2022/12/03/advent-of-code-2022-day-3/ + +import System.Environment +import Data.Char +import qualified Data.Set as S +import Data.List +import Data.List.Split + +type Contents = S.Set Char +data Rucksack = Rucksack String String deriving (Show, Eq) + +main :: IO () +main = + do dataFileName <- getDataFileName + text <- readFile dataFileName + let rucksacks = fmap mkRucksack $ lines text + print $ part1 rucksacks + print $ part2 rucksacks + +getDataFileName :: IO String +getDataFileName = + do args <- getArgs + progName <- getProgName + let baseDataName = if null args + then progName + else head args + let dataFileName = "data/" ++ baseDataName ++ ".txt" + return dataFileName + +part1 :: [Rucksack] -> Int +part1 = sum . fmap (priority . commonItem) + +part2 :: [Rucksack] -> Int +part2 rucksacks = sum $ fmap priority badges + where groups = chunksOf 3 rucksacks + badges = fmap badgeOf groups + +merge :: Rucksack -> Contents +merge (Rucksack contents1 contents2) = + S.union (S.fromList contents1) (S.fromList contents2) + +badgeOf :: [Rucksack] -> Char +badgeOf rucksacks = S.findMin $ intersections (fmap merge rucksacks) + +intersections :: [Contents] -> Contents +intersections sets = foldl1' S.intersection sets + + +mkRucksack :: String -> Rucksack +mkRucksack contents = Rucksack (take n contents) (drop n contents) + where n = length contents `div` 2 + +commonItem :: Rucksack -> Char +commonItem (Rucksack contents1 contents2) = S.findMin (c1 `S.intersection` c2) + where c1 = S.fromList contents1 + c2 = S.fromList contents2 + +priority :: Char -> Int +priority item + | item >= 'a' = ord item - ord 'a' + 1 + | otherwise = ord item - ord 'A' + 27