This is the challenge:
You are given a sequence of
N
balls in 4 colors: red, green, yellow and blue. The sequence is full of colors if and only if all of the following conditions are true:
- There are as many red balls as green balls.
- There are as many yellow balls as blue balls.
- Difference between the number of red balls and green balls in every prefix of the sequence is at most 1.
- Difference between the number of yellow balls and blue balls in every prefix of the sequence is at most 1.
- Your task is to write a program, which for a given sequence prints True if it is full of colors, otherwise it prints False.
and this is my solution:
import Control.Monad (replicateM, foldM)
main :: IO ()
main = do
n <- getLine
list <- replicateM (read n :: Int) getLine
mapM_ (print . isgood) list
isgood :: String -> Bool
isgood = isValidFinal . foldM step (0,0)
where
step (x,y) c
| c == 'R' = wrapValidInJust (x - 1, y)
| c == 'G' = wrapValidInJust (x + 1, y)
| c == 'Y' = wrapValidInJust (x, y - 1)
| c == 'B' = wrapValidInJust (x, y + 1)
isValid (x,y) = abs x <= 1 && abs y <= 1
wrapValidInJust xy = if isValid xy then Just xy else Nothing
isValidFinal (Just x) = x == (0,0)
isValidFinal Nothing = False
I'm kind of happy with main
and isgood
, but the step
function seems very hard to read.
Any feedback?