Water collected between towers: Difference between revisions

Content added Content deleted
(→‎{{header|Python}}: Added a variant expressed in terms of itertools.accumulate)
(→‎{{header|Haskell}}: added a Data.List variant with graphic output)
Line 896: Line 896:
0
0
0</pre>
0</pre>


Or, using Data.List for simplicity, and adding diagrams:

<lang haskell>import Data.List (replicate, transpose)

towerPools :: [Int] -> [(Int, Int)]
towerPools xs =
zip
xs
((zipWith (-) =<< -- Where coverages are differences between:
(zipWith min . -- the lower water level in each case of:
scanl1 max <*> -- highest wall to left, and
scanr1 max)) -- highest wall to right.
xs)

main :: IO ()
main =
mapM_
(putStrLn . (((++) . showTowers <*> (('\n' :) . showLegend)) . towerPools))
[ [1, 5, 3, 7, 2]
, [5, 3, 7, 2, 6, 4, 5, 9, 1, 2]
, [2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1]
, [5, 5, 5, 5]
, [5, 6, 7, 8]
, [8, 7, 7, 6]
, [6, 7, 10, 7, 6]
]

showTowers :: [(Int, Int)] -> String
showTowers xs =
let upper = maximum (fst <$> xs)
in '\n' :
(unlines .
transpose .
fmap
(\(x, d) ->
concat $
replicate (upper - (x + d)) " " ++
replicate d "x" ++ replicate x "█"))
xs

showLegend :: [(Int, Int)] -> String
showLegend =
((++) . show . fmap fst) <*> ((" -> " ++) . show . foldr ((+) . snd) 0)</lang>
{{Out}}
<pre>
█x█
█x█
███
████
█████

[1,5,3,7,2] -> 2

█xxxx█
█x█xx█
█x█x█x██
█x█x████
███x████
████████x█
██████████

[5,3,7,2,6,4,5,9,1,2] -> 14

█xxxxxxx█
█xxx█xxxxxxx█
█x█x█xxxx█x██
█x█x█x█xx█x███
███x█x█xx█████
██████x████████
████████████████

[2,6,3,5,2,8,1,4,2,2,5,3,5,7,4,1] -> 35

████
████
████
████
████

[5,5,5,5] -> 0

██
███
████
████
████
████
████

[5,6,7,8] -> 0

███
████
████
████
████
████
████

[8,7,7,6] -> 0

███
█████
█████
█████
█████
█████
█████

[6,7,10,7,6] -> 0</pre>


=={{header|J}}==
=={{header|J}}==