never executed always true always false
1 {-# LANGUAGE DeriveAnyClass #-}
2 {-# LANGUAGE DeriveGeneric #-}
3 {-|
4 Module: Y2021.D17
5 Description: Advent of Code 2021 Day 17 Solutions.
6 License: MIT
7 Maintainer: @tylerjl
8
9 Solutions to the 2021 day 17 set of problems for <adventofcode.com>.
10 -}
11 module Y2021.D17
12 ( parse17
13 , part17A
14 , part17B
15 , solve17A
16 ) where
17
18 import Control.Applicative
19 import Data.Attoparsec.Text hiding (take, takeWhile)
20 import Data.Either.Utils (fromRight)
21 import Data.Text (Text)
22 import Control.DeepSeq (NFData)
23 import GHC.Generics (Generic)
24
25 data LandingZone = LZ (Int, Int) (Int, Int)
26 deriving (Generic, NFData, Show)
27
28 -- |Solution to part A
29 part17A :: Text -> Int
30 part17A = solve17A . parse17
31
32 -- |Solution to part A
33 solve17A :: LandingZone -> Int
34 solve17A (LZ _ (abs -> y1, abs -> y2)) = (y * (y - 1)) `div` 2
35 where
36 y = max y1 y2
37
38 -- |Solution to part B
39 part17B :: Text -> Int
40 part17B (parse17 -> LZ (x1, x2) (y1, y2)) = length $
41 [ a | dx <- [1 .. x2]
42 , dy <- [y1 .. negate y1]
43 , let a = arc (dx, dy)
44 , isValid a
45 ]
46 where
47 isValid = any (\(x, y) -> x1 <= x && x <= x2 && y1 <= y && y <= y2)
48 arc = takeWhile (\(_, y) -> y >= y1) . steps (0, 0)
49 where
50 steps (x, y) (dx, dy) =
51 (x, y) : steps (x + dx, y + dy) (dx - signum dx, dy - 1)
52
53 -- |Parse.
54 parse17 :: Text -> LandingZone
55 parse17 = fromRight . parseOnly parser
56 where
57 parser = LZ <$> ("target area: " *> span') <*> (", " *> span')
58 span' = sortTuple <$> range'
59 range' = (,) <$> (axis *> "=" *> signed decimal) <*> (".." *> signed decimal)
60 axis = char 'x' <|> char 'y'
61
62 sortTuple :: Ord a => (a, a) -> (a, a)
63 sortTuple t@(a, b) | a <= b = t
64 | otherwise = (b, a)