1 -- Writeup at https://work.njae.me.uk/2021/12/02/advent-of-code-2021-day-2/
4 import qualified Data.Text.IO as TIO
6 import Data.Attoparsec.Text
7 import Control.Applicative
9 type Course = [Command]
10 data Command = Forward Int
15 data Position = Position Int Int -- forward, depth
18 data AimedPosition = AimedPosition Int Int Int -- forward, depth, aim
23 do text <- TIO.readFile "data/advent02.txt"
24 let course = successfulParse text
28 part1 :: Course -> Int
29 part1 course = finalH * finalD
30 where (Position finalH finalD) = followCourse course
32 part2 :: Course -> Int
33 part2 course = finalH * finalD
34 where (AimedPosition finalH finalD _) = followAimedCourse course
36 followCourse :: Course -> Position
37 followCourse = foldl courseStep (Position 0 0)
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)
44 followAimedCourse :: Course -> AimedPosition
45 followAimedCourse = foldl courseAimedStep (AimedPosition 0 0 0)
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)
53 -- Parse the input file
55 courseP = commandP `sepBy` endOfLine
56 commandP = forwardP <|> upP <|> downP
58 forwardP = Forward <$> ("forward " *> decimal)
59 upP = Up <$> ("up " *> decimal)
60 downP = Down <$> ("down " *> decimal)
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