Advertisement
Guest User

Untitled

a guest
Dec 8th, 2017
47
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.43 KB | None | 0 0
  1. import Data.Map.Lazy (Map, empty, insert, adjust, elems, (!))
  2. import Data.Char (isAlpha)
  3. import Data.List (isPrefixOf, tails, stripPrefix, isInfixOf)
  4. import Data.Maybe (fromJust)
  5.  
  6. main :: IO ()
  7. main = print =<< getMaxRegisterVal . lines <$> getContents
  8.  
  9. getMaxRegisterVal :: [String] -> Int
  10. getMaxRegisterVal input = processInstructions input $ mkRegisters input
  11.  
  12. mkRegisters :: [String] -> Map String Int
  13. mkRegisters = foldl insertRegister empty
  14.  
  15. insertRegister :: Map String Int -> String -> Map String Int
  16. insertRegister mapping xs = insert second 0 $ insert first 0 mapping
  17. where (first, second) = parseRegisters xs
  18.  
  19. processInstructions :: [String] -> Map String Int -> Int
  20. processInstructions input mapping
  21. = fst $ foldl processInstruction (0, mapping) input
  22.  
  23. processInstruction :: (Int, Map String Int) -> String -> (Int, Map String Int)
  24. processInstruction (maxVal, mapping) instruction
  25. | secondVal `operator` val = (newMaxVal, newMapping)
  26. | otherwise = (maxVal, mapping)
  27. where (first, second) = parseRegisters instruction
  28. secondVal = mapping ! second
  29. operator = parseOperator instruction
  30. val = read . reverse . takeWhile isNumVal $ reverse instruction
  31. incrementVal = parseIncrementVal instruction
  32. newMapping = adjust (+incrementVal) first mapping
  33. newMaxVal
  34. | newMax > maxVal = newMax
  35. | otherwise = maxVal
  36. where newMax = maxMapVal newMapping
  37.  
  38. parseRegisters :: String -> (String, String)
  39. parseRegisters xs = (first, second)
  40. where first = takeWhile isAlpha xs
  41. second = takeWhile isAlpha stripped
  42. stripped = fromJust $ stripPrefix "if " targetStr
  43. targetStr = head . filter ("if " `isPrefixOf`) $ tails xs
  44.  
  45. parseOperator :: (Ord a) => String -> (a -> a -> Bool)
  46. parseOperator xs
  47. | ">=" `isInfixOf` xs = (>=)
  48. | "<=" `isInfixOf` xs = (<=)
  49. | "==" `isInfixOf` xs = (==)
  50. | "!=" `isInfixOf` xs = (/=)
  51. | ">" `isInfixOf` xs = (>)
  52. | "<" `isInfixOf` xs = (<)
  53. | otherwise = error "Expected operator not found!"
  54.  
  55. parseIncrementVal :: String -> Int
  56. parseIncrementVal xs
  57. | "inc" `isInfixOf` xs = val
  58. | otherwise = -val
  59. where val = read . takeWhile isNumVal $ dropWhile (not . isNumVal) xs
  60.  
  61. maxMapVal :: Map String Int -> Int
  62. maxMapVal = maximum . elems
  63.  
  64. isNumVal :: Char -> Bool
  65. isNumVal = (`elem` numVals)
  66. where numVals = '-' : ['0'..'9']
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement