Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import Text.Read
- import Data.Maybe
- import Data.List.Split
- data Direction = L | R deriving (Show, Eq)
- data Instruction = Instruction { turnDirection :: Direction, distance :: Int } deriving Show
- data Coordinate = Coordinate Int Int deriving Show
- data Vector = Vector Coordinate Coordinate deriving Show
- data CompassDirection = North | South | East | West deriving (Show, Eq)
- data Traveler = Traveler {coordinate :: Coordinate, direction :: CompassDirection } deriving Show
- taxiCabDistance :: Vector -> Int
- taxiCabDistance (Vector (Coordinate x1 y1) (Coordinate x2 y2)) = (abs x2 - x1) + (abs y2 - y1)
- taxiCabDistanceFromStart :: Coordinate -> Int
- taxiCabDistanceFromStart = taxiCabDistance . Vector (Coordinate 0 0)
- toInstruction :: String -> Maybe Instruction
- toInstruction ('L':xs)
- | Just i <- readMaybe xs
- = Just $ Instruction L i
- toInstruction ('R':xs)
- | Just i <- readMaybe xs
- = Just $ Instruction R i
- toInstruction _ = Nothing
- -- if any fail, we want all to fail
- toInstructions :: [String] -> Maybe [Instruction]
- toInstructions xs = if (any isNothing instructions) then Nothing else Just $ map fromJust instructions
- where instructions = map toInstruction xs
- -- TODO I bet there's a better algebraic way to do this
- applyInstruction :: Traveler -> Instruction -> Traveler
- applyInstruction (Traveler (Coordinate x y) dir) (Instruction turn dist)
- | (dir == East) && (turn == L) = Traveler (Coordinate x (y + dist)) North
- | (dir == West) && (turn == R) = Traveler (Coordinate x (y + dist)) North
- | (dir == West) && (turn == L) = Traveler (Coordinate x (y - dist)) South
- | (dir == East) && (turn == R) = Traveler (Coordinate x (y - dist)) South
- | (dir == South) && (turn == L) = Traveler (Coordinate (x + dist) y) East
- | (dir == North) && (turn == R) = Traveler (Coordinate (x + dist) y) East
- | (dir == North) && (turn == L) = Traveler (Coordinate (x - dist) y) West
- | (dir == South) && (turn == R) = Traveler (Coordinate (x - dist) y) West
- applyInstructions :: Traveler -> [Instruction] -> Traveler
- applyInstructions = foldl applyInstruction
- main = do
- stdin <- getContents
- -- init avoids the trailing ÂĽn
- putStrLn . show . taxiCabDistanceFromStart . coordinate . applyInstructions (Traveler (Coordinate 0 0) North) $ fromJust . toInstructions $ splitOn ", " $ init stdin
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement