never executed always true always false
1 {-|
2 Module: Y2015.D02
3 Description: Advent of Code Day 02 Solutions.
4 License: MIT
5 Maintainer: @tylerjl
6
7 Solutions to the day 02 set of problems for <adventofcode.com>.
8 -}
9 module Y2015.D02
10 ( Present(..)
11 , parsePresents
12 , surfaceArea
13 , ribbonLength
14 ) where
15
16 import Data.Attoparsec.Text hiding (take)
17 import Data.List (foldl', sort)
18 import Data.Text (Text)
19
20 -- |Represents a present in three dimensions
21 data Present =
22 Present Int
23 Int
24 Int
25 deriving (Eq, Show)
26
27 presentsParser :: Parser [Present]
28 presentsParser = many1 (presentParser <* skipMany endOfLine)
29
30 presentParser :: Parser Present
31 presentParser =
32 Present <$> (decimal <* char 'x') <*> (decimal <* char 'x') <*> decimal
33
34 -- |Parse presents from an input string
35 parsePresents
36 :: Text -- ^ Raw input of present dimensions
37 -> Maybe [Present] -- ^ Possible list of 'Present's
38 parsePresents s =
39 case parseOnly presentsParser s of
40 Right ps -> Just ps
41 Left _ -> Nothing
42
43 -- |Find total surface area from list of 'Present's
44 surfaceArea
45 :: [Present] -- ^ List of 'Present's
46 -> Int -- ^ Total surface area of all 'Present's
47 surfaceArea = foldl' (+) 0 . map wrapping
48
49 wrapping :: Present -> Int
50 wrapping p = sqft p + product (smallest p)
51
52 smallest :: Present -> [Int]
53 smallest (Present l w h) = take 2 $ sort [l, w, h]
54
55 sqft :: Present -> Int
56 sqft (Present l w h) = 2 * l * w + 2 * w * h + 2 * h * l
57
58 area :: Present -> Int
59 area (Present l w h) = l * w * h
60
61 -- |Find required length of ribbon for a list of presents.
62 ribbonLength
63 :: [Present] -- ^ List of 'Present's
64 -> Int -- ^ Total length of required ribbon
65 ribbonLength = sum . map presentRibbon
66
67 presentRibbon :: Present -> Int
68 presentRibbon p = sum (map (* 2) $ smallest p) + area p