Skip to content

Instantly share code, notes, and snippets.

@paf31

paf31/water.hs Secret

Last active August 17, 2022 04:28
Show Gist options
  • Star 48 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save paf31/9d84ecf6a6a9b69cdb597a390f25764d to your computer and use it in GitHub Desktop.
Save paf31/9d84ecf6a6a9b69cdb597a390f25764d to your computer and use it in GitHub Desktop.
> import Control.Monad.Tardis
> :{
let levels hs = evalTardis (traverse
(\h -> do x <- min <$> getFuture <*> getPast -- Get the height of the enclosing walls
modifyBackwards (`max` h) -- Send the right max back to the past
modifyForwards (`max` h) -- Send the left max into the future
pure (max 0 (x - h)) -- Calculate the height of the water itself
) hs) (0, 0)
:}
> sum $ levels [5,3,7,2,6,4,5,9,1,2]
14
@lalaithion
Copy link

This code has a slight subtlety in it that I wouldn't call a bug, strictly speaking, but is perhaps inhibitory to understanding the exact semantics of the Tardis Monad.

If we have a situation where the max height in the Future direction is less than the current height, then the modifyBackwards causes the getFuture on the previous line to return h, not the actual max height in the future direction. In that case, we know that x is either h, because there is a bigger number in the Past, or x is less than h, because the Past was a smaller number. Therefore, x - h <= 0, and we end up with the right answer in the end.

However, it's not quite what the code should be doing.

@paf31
Copy link
Author

paf31 commented Dec 10, 2019

@lalaithion Oh, you're right, well spotted! I think we could fix it perhaps by swapping those two lines?

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