data Command = Forward Int | Down Int | Up Int type Position = (Int,Int) type AimPosition = (Int,Int,Int) readCmd :: String -> Command readCmd s = case cmd of "forward" -> Forward $ read num "down" -> Down $ read num "up" -> Up $ read num _ -> error $ "unknown command" ++ cmd where (cmd:num:xs) = words s moveSub :: Position -> Command -> Position moveSub (h,d) (Forward f) = (h+f,d) moveSub (h,d) (Down f) = (h,d+f) moveSub (h,d) (Up f) = (h,d-f) applyCommands :: [Command] -> Position applyCommands = foldl moveSub (0,0) moveSubAim :: AimPosition -> Command -> AimPosition moveSubAim (h,d,a) (Forward f) = (h+f,d+a*f,a) moveSubAim (h,d,a) (Down f) = (h,d,a+f) moveSubAim (h,d,a) (Up f) = (h,d,a-f) applyCommandsAim :: [Command] -> AimPosition applyCommandsAim = foldl moveSubAim (0,0,0) main :: IO () main = do input <- getContents let commands = map readCmd $ lines input putStr "part 1: " print $ uncurry (*) $ applyCommands commands putStr "part 2: " print $ (\(x,y,_) -> x*y) $ applyCommandsAim commands return ()