Skip to content

Instantly share code, notes, and snippets.

@olajep
Last active August 23, 2019 11:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save olajep/7236551 to your computer and use it in GitHub Desktop.
Save olajep/7236551 to your computer and use it in GitHub Desktop.
rainSolver = solve 0 . zipWithRightMax
zipWithRightMax xs = zip xs maxVals
where
rev = reverse xs
(maxVals, _) = foldl maxFold ([], head rev) rev
maxFold (acc, maxVal) x = (maxVal:acc,maxFromHere)
where
maxFromHere = max maxVal x
solve acc [] = acc
solve acc (x:xs)
| xs' == [] = solve acc xs -- no right border -> this x cannot be left border
| otherwise = solve (acc+area) xs'
where
(val, rightMax) = x
height = min val rightMax
(elems',xs') = span ((<height).fst) xs
elems = fst $ unzip elems'
area = (length elems * height) - (sum elems)
rainSolver = solve 0
solve acc [] = acc
solve acc (x:xs)
| xs' == [] = solve acc xs -- no right border -> this x cannot be left border
| otherwise = solve (acc+area) xs'
where
height = minimum [x, maximum xs]
(elems,xs') = span (<height) xs
area = (length elems * height) - (sum elems)
@qazwsxpawel
Copy link

Man, I need to learn Haskell :)

@Bontrey
Copy link

Bontrey commented Oct 30, 2013

This is O(n^2) without precomputing max of all the suffixes, isn't it

EDIT: Actually, more complicated than that. The span is also linear time =/

@olajep
Copy link
Author

olajep commented Oct 30, 2013

@Bontrey: Yes, it is.

@olajep
Copy link
Author

olajep commented Oct 30, 2013

@Bontrey: The span doesn't make it O(n^2).
Consider these extremes:
Take one elements n times.
Take all elements 1 time.

@Bontrey
Copy link

Bontrey commented Oct 30, 2013

Oh yeah. Good point. Each element is only segmented out once

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment