Tweaked some parsing code
[advent-of-code-21.git] / advent02 / Main.hs
1 -- Writeup at https://work.njae.me.uk/2021/12/02/advent-of-code-2021-day-2/
2
3 import Data.Text ()
4 import qualified Data.Text.IO as TIO
5
6 import Data.Attoparsec.Text
7 import Control.Applicative
8
9 type Course = [Command]
10 data Command = Forward Int
11 | Up Int
12 | Down Int
13 deriving (Eq, Show)
14
15 data Position = Position Int Int -- forward, depth
16 deriving (Eq, Show)
17
18 data AimedPosition = AimedPosition Int Int Int -- forward, depth, aim
19 deriving (Eq, Show)
20
21 main :: IO ()
22 main =
23 do text <- TIO.readFile "data/advent02.txt"
24 let course = successfulParse text
25 print $ part1 course
26 print $ part2 course
27
28 part1 :: Course -> Int
29 part1 course = finalH * finalD
30 where (Position finalH finalD) = followCourse course
31
32 part2 :: Course -> Int
33 part2 course = finalH * finalD
34 where (AimedPosition finalH finalD _) = followAimedCourse course
35
36 followCourse :: Course -> Position
37 followCourse = foldl courseStep (Position 0 0)
38
39 courseStep :: Position -> Command -> Position
40 courseStep (Position h d) (Forward n) = Position (h + n) d
41 courseStep (Position h d) (Up n) = Position h (d - n)
42 courseStep (Position h d) (Down n) = Position h (d + n)
43
44 followAimedCourse :: Course -> AimedPosition
45 followAimedCourse = foldl courseAimedStep (AimedPosition 0 0 0)
46
47 courseAimedStep :: AimedPosition -> Command -> AimedPosition
48 courseAimedStep (AimedPosition h d a) (Forward n) = AimedPosition (h + n) (d + a * n) a
49 courseAimedStep (AimedPosition h d a) (Up n) = AimedPosition h d (a - n)
50 courseAimedStep (AimedPosition h d a) (Down n) = AimedPosition h d (a + n)
51
52
53 -- Parse the input file
54
55 courseP = commandP `sepBy` endOfLine
56 commandP = forwardP <|> upP <|> downP
57
58 forwardP = Forward <$> ("forward " *> decimal)
59 upP = Up <$> ("up " *> decimal)
60 downP = Down <$> ("down " *> decimal)
61
62 -- successfulParse :: Text -> (Integer, [Maybe Integer])
63 successfulParse input =
64 case parseOnly courseP input of
65 Left _err -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err
66 Right course -> course