never executed always true always false
1 {-|
2 Module: Y2018.D03
3 Description: Advent of Code Day 03 Solutions.
4 License: MIT
5 Maintainer: @tylerjl
6
7 Solutions to the day 01 set of problems for <adventofcode.com>.
8 -}
9 module Y2018.D03
10 ( intactInches
11 , overlappedInches
12 ) where
13
14 import Y2015.Util (regularParse, intParser)
15
16 import Data.List (foldl')
17 import Text.Parsec.String (Parser)
18 import Text.Parsec.Char (endOfLine)
19 import Text.Parsec
20 ( ParseError
21 , many
22 , optional
23 , space
24 , string
25 )
26
27 import qualified Data.Map.Strict as Map
28 import qualified Data.Set as Set
29
30 data Claim = Claim
31 { iD :: Int
32 , leftEdge :: Int
33 , topEdge :: Int
34 , width :: Int
35 , height :: Int
36 } deriving (Eq, Show)
37
38 type Point = (Int, Int)
39
40 intactInches :: String -> Either ParseError [Int]
41 intactInches input =
42 case parseClaims input of
43 Left e -> Left e
44 Right claims ->
45 Right $ map iD $ singleClaims claims $ toClothMap claims
46
47 singleClaims :: [Claim] -> Map.Map Point (Set.Set Int) -> [Claim]
48 singleClaims claims cloth = filter noOtherClaims claims
49 where noOtherClaims claim =
50 Map.null
51 $ Map.filter (not . (==) 1 . Set.size)
52 $ Map.filter (Set.member (iD claim)) cloth
53
54 overlappedInches :: String -> Either ParseError Int
55 overlappedInches input =
56 case parseClaims input of
57 Left e -> Left e
58 Right claims ->
59 Right
60 $ Map.size
61 $ Map.filter multipleClaims
62 $ toClothMap claims
63 where multipleClaims = flip (>) 1 . Set.size
64
65 toClothMap :: [Claim] -> Map.Map Point (Set.Set Int)
66 toClothMap claims =
67 foldl' (Map.unionWith (Set.union)) (Map.empty :: Map.Map Point (Set.Set Int))
68 $ map ((\x -> Map.fromSet (\_ -> Set.singleton $ fst x) $ snd x))
69 $ map toPoints claims
70
71 toPoints :: Claim -> (Int, Set.Set Point)
72 toPoints Claim { iD = i, leftEdge = l, topEdge = t, width = w, height = h } =
73 (i, Set.fromList $ concatMap (\x -> map (\y -> (x, y)) [t .. (t+h-1)]) [l .. (l+w-1)])
74
75 -- Parsing utilities
76
77 parseClaims :: String
78 -> Either ParseError [Claim]
79 parseClaims = regularParse claimParser
80
81 claimParser :: Parser [Claim]
82 claimParser = many (parseClaim <* optional endOfLine)
83
84 parseClaim :: Parser Claim
85 parseClaim = Claim <$ string "#" <*> intParser <* space <* string "@" <* space
86 <*> intParser <* string ","
87 <*> intParser <* string ":" <* space
88 <*> intParser <* string "x"
89 <*> intParser