33890d8a8b
Where it belongs...
52 lines
1.6 KiB
Haskell
52 lines
1.6 KiB
Haskell
--------------------------------------------------------------------------------
|
|
module Transforms where
|
|
--------------------------------------------------------------------------------
|
|
import Control.Applicative ((<|>))
|
|
import Text.ParserCombinators.ReadP
|
|
--------------------------------------------------------------------------------
|
|
|
|
data Transform = VerticalFlip
|
|
| HorizontalFlip
|
|
| Shift Int
|
|
deriving (Eq, Show)
|
|
|
|
digit :: ReadP Char
|
|
digit =
|
|
satisfy (\c -> c >= '0' && c <= '9')
|
|
|
|
command :: ReadP Transform
|
|
command = vertical
|
|
<|> horizontal
|
|
<|> shift
|
|
where
|
|
vertical =
|
|
char 'V' >> pure VerticalFlip
|
|
|
|
horizontal =
|
|
char 'H' >> pure HorizontalFlip
|
|
|
|
shift = do
|
|
_ <- char 'S'
|
|
negative <- option Nothing $ fmap Just (satisfy (== '-'))
|
|
n <- read <$> many1 digit
|
|
case negative of
|
|
Nothing -> pure $ Shift n
|
|
Just _ -> pure $ Shift (-1 * n)
|
|
|
|
-- | Attempt to remove redundant transformations.
|
|
-- | Here are some rules that I'd like to support but may not have time for:
|
|
-- | - All even-numbered flips (w/o intermittent shifts) can become zero
|
|
-- | - All odd-numbered flips (w/o intermittent shifts) can become 1
|
|
-- | - All shifts can be be reduce to the absolute value of shifts
|
|
optimize :: [Transform] -> [Transform]
|
|
optimize [] = []
|
|
optimize [x] = [x]
|
|
optimize (VerticalFlip:VerticalFlip:xs) = optimize xs
|
|
optimize (HorizontalFlip:HorizontalFlip:xs) = optimize xs
|
|
optimize xs = xs
|
|
|
|
fromString :: String -> Maybe [Transform]
|
|
fromString x =
|
|
case readP_to_S (manyTill command eof) x of
|
|
[(res, "")] -> Just res
|
|
_ -> Nothing
|