AdventOfCode2023-Haskell/day2/app/Main.hs

76 lines
2.6 KiB
Haskell

module Main where
import Data.List.Split (splitOn)
type Red = Int
type Green = Int
type Blue = Int
data Cube = RedQuantity Red | GreenQuantity Green | BlueQuantity Blue deriving (Show)
data CubeSum = CubeSum {red :: Red, green :: Green, blue :: Blue} deriving (Show)
partTwo :: [String] -> Int
partTwo = sum . map (powerCube . makeCubes)
powerCube :: [Cube] -> Int
powerCube = getCubePower . foldr minimumSetCube CubeSum {red = 0, green = 0, blue = 0}
getCubePower :: CubeSum -> Int
getCubePower CubeSum {red = _red, green = _green, blue = _blue} = _red * _green * _blue
minimumSetCube :: Cube -> CubeSum -> CubeSum
minimumSetCube (RedQuantity q) CubeSum {red = _red, green = _green, blue = _blue} = CubeSum {red = max _red q, green = _green, blue = _blue}
minimumSetCube (GreenQuantity q) CubeSum {red = _red, green = _green, blue = _blue} = CubeSum {red = _red, green = max _green q, blue = _blue}
minimumSetCube (BlueQuantity q) CubeSum {red = _red, green = _green, blue = _blue} = CubeSum {red = _red, green = _green, blue = max _blue q}
partOne :: [String] -> [Int]
partOne = map fst . filter (all validate . snd) . zip [1 ..] . map makeCubes
where
validate (RedQuantity n) = n <= 12
validate (GreenQuantity n) = n <= 13
validate (BlueQuantity n) = n <= 14
makeCubes :: String -> [Cube]
makeCubes = map createCube . splitOn "," . replaceSemiColon . last . splitOn ":"
replaceSemiColon :: String -> String
replaceSemiColon = map toComma
where
toComma ';' = ','
toComma x = x
parseElem :: String -> (String, String)
parseElem (_ : s) = (cube, nb)
where
nb = head splited
cube = last splited
splited = splitOn " " s
parseElem _ = undefined
getElem :: (String, String) -> Cube
getElem ("red", nb) = RedQuantity (read nb :: Red)
getElem ("green", nb) = GreenQuantity (read nb :: Green)
getElem ("blue", nb) = BlueQuantity (read nb :: Blue)
getElem _ = undefined
createCube :: String -> Cube
createCube = getElem . parseElem
getCubeSum :: [Cube] -> CubeSum
getCubeSum = foldr cubeAddition CubeSum {red = 0, green = 0, blue = 0}
cubeAddition :: Cube -> CubeSum -> CubeSum
cubeAddition (RedQuantity q) CubeSum {red = _red, green = _green, blue = _blue} = CubeSum {red = _red + q, green = _green, blue = _blue}
cubeAddition (GreenQuantity q) CubeSum {red = _red, green = _green, blue = _blue} = CubeSum {red = _red, green = _green + q, blue = _blue}
cubeAddition (BlueQuantity q) CubeSum {red = _red, green = _green, blue = _blue} = CubeSum {red = _red, green = _green, blue = _blue + q}
main :: IO ()
main = do
content <- readFile "input.txt"
(print . sum . partOne . lines) content
(print . partTwo . lines) content
putStrLn "Yes, it works!"