{-# LANGUAGE BangPatterns #-} {-# LANGUAGE TupleSections #-} module Main where import Control.Monad import Control.Monad.ST import Control.Monad.State import Data.Bits import Data.Bool import Data.Char import Data.Coerce import Data.Word import Unsafe.Coerce import qualified Data.ByteString.Char8 as BSC8 import qualified Data.Vector.Fusion.Stream.Monadic as VFSM import qualified Data.Vector.Generic as VG import qualified Data.Vector.Generic.Mutable as VGM import qualified Data.Vector.Unboxed as VU main :: IO () main = do xs <- seqInput 4 putStrLn $ bool "No" "Yes" (solve xs) solve :: VU.Vector Int -> Bool solve xs = runST $ do let ys = bucketSort 100 xs a = ys VU.! 0 b = ys VU.! 1 c = ys VU.! 2 d = ys VU.! 3 return ((a + 1 == b) && (b + 1 == c) && (c + 1 == d)) type CParser a = StateT BSC8.ByteString Maybe a runCParser :: CParser a -> BSC8.ByteString -> Maybe (a, BSC8.ByteString) runCParser = runStateT {-# INLINE runCParser #-} int :: CParser Int int = coerce $ BSC8.readInt . BSC8.dropWhile isSpace {-# INLINE int #-} seqInput :: Int -> IO (VU.Vector Int) seqInput n = VU.unfoldrN n (runCParser int) <$> BSC8.getLine {-# INLINE seqInput #-} bucketSort :: Int -> VU.Vector Int -> VU.Vector Int bucketSort bucketSize = VU.concatMap (uncurry $ flip VU.replicate) . VU.indexed . VU.unsafeAccumulate (+) (VU.replicate bucketSize 0) . VU.map (,1) {-# INLINE bucketSort #-}