Advertisement
Guest User

Untitled

a guest
Dec 3rd, 2016
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.24 KB | None | 0 0
  1. import Text.Read
  2. import Data.Maybe
  3. import Data.List.Split
  4.  
  5. data Direction = L | R deriving (Show, Eq)
  6. data Instruction = Instruction { turnDirection :: Direction, distance :: Int } deriving Show
  7. data Coordinate = Coordinate Int Int deriving Show
  8. data Vector = Vector Coordinate Coordinate deriving Show
  9. data CompassDirection = North | South | East | West deriving (Show, Eq)
  10. data Traveler = Traveler {coordinate :: Coordinate, direction :: CompassDirection } deriving Show
  11.  
  12. taxiCabDistance :: Vector -> Int
  13. taxiCabDistance (Vector (Coordinate x1 y1) (Coordinate x2 y2)) = (abs x2 - x1) + (abs y2 - y1)
  14.  
  15. taxiCabDistanceFromStart :: Coordinate -> Int
  16. taxiCabDistanceFromStart = taxiCabDistance . Vector (Coordinate 0 0)
  17.  
  18.  
  19. toInstruction :: String -> Maybe Instruction
  20. toInstruction ('L':xs)
  21. | Just i <- readMaybe xs
  22. = Just $ Instruction L i
  23. toInstruction ('R':xs)
  24. | Just i <- readMaybe xs
  25. = Just $ Instruction R i
  26. toInstruction _ = Nothing
  27.  
  28. -- if any fail, we want all to fail
  29. toInstructions :: [String] -> Maybe [Instruction]
  30. toInstructions xs = if (any isNothing instructions) then Nothing else Just $ map fromJust instructions
  31. where instructions = map toInstruction xs
  32.  
  33. -- TODO I bet there's a better algebraic way to do this
  34. applyInstruction :: Traveler -> Instruction -> Traveler
  35. applyInstruction (Traveler (Coordinate x y) dir) (Instruction turn dist)
  36. | (dir == East) && (turn == L) = Traveler (Coordinate x (y + dist)) North
  37. | (dir == West) && (turn == R) = Traveler (Coordinate x (y + dist)) North
  38. | (dir == West) && (turn == L) = Traveler (Coordinate x (y - dist)) South
  39. | (dir == East) && (turn == R) = Traveler (Coordinate x (y - dist)) South
  40. | (dir == South) && (turn == L) = Traveler (Coordinate (x + dist) y) East
  41. | (dir == North) && (turn == R) = Traveler (Coordinate (x + dist) y) East
  42. | (dir == North) && (turn == L) = Traveler (Coordinate (x - dist) y) West
  43. | (dir == South) && (turn == R) = Traveler (Coordinate (x - dist) y) West
  44.  
  45. applyInstructions :: Traveler -> [Instruction] -> Traveler
  46. applyInstructions = foldl applyInstruction
  47.  
  48. main = do
  49. stdin <- getContents
  50. -- init avoids the trailing ¥n
  51. 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