AoC2021/day02/lib/Day02.hs
2021-12-09 15:53:41 +01:00

58 lines
1.8 KiB
Haskell

module Day02 where
import Data.Maybe (fromMaybe)
import Text.Read (readMaybe)
data Move = Horizontal Int | Depth Int deriving Show
data Position = Position {hPos :: Int, depth :: Int, aim::Int} deriving Show
initialPosition :: Position
initialPosition = Position {hPos =0, depth = 0, aim = 0}
updatePosition :: Position -> Move -> Position
updatePosition p@(Position {hPos = h}) (Horizontal m) = p{hPos = h + m}
updatePosition p@(Position {depth = d}) ( Depth m) = p{depth = d + m}
updatePosition' :: Position -> Move -> Position
updatePosition' p@(Position {hPos=h, depth=d, aim=a}) (Horizontal m) = p{hPos=h+m, depth =d+a*m}
updatePosition' p@(Position {hPos=h, depth=d, aim=a}) (Depth m) = p{aim=a+m}
readDataLines:: (String -> Maybe a) -> String -> Either String [a]
readDataLines f s = case mapM f (lines s) of
Just xs -> Right xs
Nothing -> Left "Error parsing string"
finalPosition :: [Move] -> Position
finalPosition = foldl updatePosition initialPosition
finalPosition' :: [Move] -> Position
finalPosition' = foldl updatePosition' initialPosition
calcResult:: Position -> Int
calcResult Position {hPos = h, depth =d } = h*d
day02Part1 :: String -> String
day02Part1 s = case readDataLines readMove s of
Right xs -> show . calcResult . finalPosition $ xs
Left e -> e
day02Part2 :: String -> String
day02Part2 s = case readDataLines readMove s of
Right xs -> show . calcResult . finalPosition' $ xs
readDirection ::String -> Maybe (Int -> Move)
readDirection "forward" = Just Horizontal
readDirection "down" = Just Depth
readDirection "up" = Just (Depth . negate)
readDirection _ = Nothing
readMove :: String -> Maybe Move
readMove s = case words s of
[dirStr, distStr] -> readDirection dirStr <*> readMaybe distStr
_ -> Nothing