66 lines
1.8 KiB
Haskell
66 lines
1.8 KiB
Haskell
|
{-# LANGUAGE OverloadedStrings #-}
|
||
|
|
||
|
module AoC.Day3 where
|
||
|
|
||
|
import Data.Text (Text)
|
||
|
import Data.Maybe (fromMaybe)
|
||
|
import Data.Monoid (Sum(..), getSum)
|
||
|
import Data.List.Split (chunksOf)
|
||
|
import Data.Tuple.Extra (uncurry3)
|
||
|
import qualified Data.Text as T
|
||
|
|
||
|
valueMap :: [(Char, Int)]
|
||
|
valueMap = zip (['a'..'z']++['A'..'Z']) [1..]
|
||
|
|
||
|
breakInTwoEqualLengthSubStrings :: Text -> (Text,Text)
|
||
|
breakInTwoEqualLengthSubStrings txt = T.splitAt (T.length txt `div` 2) txt
|
||
|
|
||
|
findCommonItem :: Text -> Text -> Char
|
||
|
findCommonItem _ "" = undefined
|
||
|
findCommonItem compartment1 compartment2 =
|
||
|
if (c `T.elem` compartment1)
|
||
|
then c
|
||
|
else findCommonItem compartment1 (T.tail compartment2)
|
||
|
where
|
||
|
c = T.head compartment2
|
||
|
|
||
|
|
||
|
solveAOnOne :: Text -> Int
|
||
|
solveAOnOne = fromMaybe undefined
|
||
|
. flip lookup valueMap
|
||
|
. uncurry findCommonItem
|
||
|
. breakInTwoEqualLengthSubStrings
|
||
|
|
||
|
solveA :: Text -> Int
|
||
|
solveA = getSum . mconcat . map (Sum . solveAOnOne) . T.lines
|
||
|
|
||
|
--------------------------------------------------------------------------------
|
||
|
-- Part 2
|
||
|
|
||
|
findCommonItem3 :: Text -> Text -> Text -> Char
|
||
|
findCommonItem3 c1 c2 c3 = T.head $ go (go c1 c2) c3
|
||
|
where
|
||
|
go :: Text -> Text -> Text
|
||
|
go t1 = T.foldl (\acc c -> if c `T.elem` t1 then T.cons c acc else acc) ""
|
||
|
|
||
|
tupleMeUp3 :: [[Text]] -> [(Text,Text,Text)]
|
||
|
tupleMeUp3 = go []
|
||
|
where
|
||
|
go :: [(Text,Text,Text)] -> [[Text]] -> [(Text,Text,Text)]
|
||
|
go tuples [] = tuples
|
||
|
go tuples ([t1, t2, t3]:xs) = go ((t1,t2,t3):tuples) xs
|
||
|
go _ _ = undefined
|
||
|
|
||
|
solveBOnOne :: (Text,Text,Text) -> Int
|
||
|
solveBOnOne = fromMaybe undefined
|
||
|
. flip lookup valueMap
|
||
|
. uncurry3 findCommonItem3
|
||
|
|
||
|
solveB :: Text -> Int
|
||
|
solveB = getSum
|
||
|
. mconcat
|
||
|
. map (Sum . solveBOnOne)
|
||
|
. tupleMeUp3
|
||
|
. chunksOf 3
|
||
|
. T.lines
|