Skip to content

Instantly share code, notes, and snippets.

@NCrashed
Last active December 27, 2015 01:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NCrashed/7249016 to your computer and use it in GitHub Desktop.
Save NCrashed/7249016 to your computer and use it in GitHub Desktop.
Haskell solution for http://habrahabr.ru/post/200190/
module Main where
import qualified Data.Vector as V
printArray :: (Integral a, Show a) => V.Vector a -> IO ()
printArray x = mapM_ printLine $ reverse [1 .. maxElem]
where
printLine n = (putWithOffset $ show n) >> mapM_ (putFiller n) [0 .. (V.length x)-1] >> putChar '\n'
putWithOffset s
| length s < numberOffset = putStr s >> mapM_ (\x -> putChar ' ') [1 .. (length s) - numberOffset]
| otherwise = putStr s
putFiller n i
| x V.! i >= n = putChar '#'
| otherwise = putChar ' '
numberOffset = length $ show maxElem
maxElem = V.maximum x
water :: Integral a => V.Vector a -> a
water vec = inwater 0 0 0 vec
where inwater ml mr ac vec
| V.length vec <= 1 = ac
| leftMax >= rightMax = inwater leftMax rightMax (ac + rightMax - V.last vec) (V.take (V.length vec - 1) vec)
| otherwise = inwater leftMax rightMax (ac + leftMax - V.head vec) (V.drop 1 vec)
where
leftMax = if V.head vec > ml then V.head vec else ml
rightMax = if V.last vec > mr then V.last vec else mr
input = V.fromList [2,5,1,3,1,2,1,7,5,6]
main = do
printArray input
putStrLn $ show $ water input
water :: Integral a => [a] -> a
water vec = inwater 0 0 0 vec
where inwater ml mr ac vec
| length vec <= 1 = ac
| leftMax >= rightMax = inwater leftMax rightMax (ac + rightMax - last vec) (take (length vec - 1) vec)
| otherwise = inwater leftMax rightMax (ac + leftMax - head vec) (drop 1 vec)
where
leftMax = if head vec > ml then head vec else ml
rightMax = if last vec > mr then last vec else mr
main = putStrLn $ show $ water [2,5,1,3,1,2,1,7,5,6]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment