This is the challenge:
You are given a sequence of
Nballs 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
isgood, but the
step function seems very hard to read.