76 lines
2.6 KiB
Haskell
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!"
|