Water collected between towers: Difference between revisions

Content deleted Content added
Loren (talk | contribs)
Added XPL0 example.
Added solution for EDSAC.
 
(26 intermediate revisions by 14 users not shown)
Line 44:
{{trans|Python}}
 
<langsyntaxhighlight lang="11l">F water_collected(tower)
V l = tower.len
V highest_left = [0] [+] (1 .< l).map(n -> max(@tower[0 .< n]))
Line 66:
[6, 7, 10, 7, 6]]
 
print(towers.map(tower -> water_collected(tower)))</langsyntaxhighlight>
 
{{out}}
Line 94:
 
=={{header|8080 Assembly}}==
<langsyntaxhighlight lang="8080asm"> org 100h
jmp demo
;;; Calculate the amount of water a row of towers will hold
Line 198:
dw t6,t7-t6
dw t7,t_end-t7
dw 0</langsyntaxhighlight>
 
{{out}}
Line 205:
 
=={{header|8086 Assembly}}==
<langsyntaxhighlight lang="asm"> cpu 8086
org 100h
section .text
Line 286:
dw t6,t7-t6
dw t7,t_end-t7
dw 0</langsyntaxhighlight>
 
{{out}}
Line 293:
 
=={{header|Action!}}==
<langsyntaxhighlight Actionlang="action!">PROC PrintArray(BYTE ARRAY a BYTE len)
BYTE i
 
Line 367:
Test(a6,4)
Test(a7,5)
RETURN</langsyntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Water_collected_between_towers.png Screenshot from Atari 8-bit computer]
Line 388:
=={{header|Ada}}==
 
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO;
 
procedure Water_Collected is
Line 461:
Show ((8, 7, 7, 6));
Show ((6, 7, 10, 7, 6));
end Water_Collected;</langsyntaxhighlight>
 
{{out}}
Line 477:
{{Trans|JavaScript}}
 
<langsyntaxhighlight AppleScriptlang="applescript">--------------- WATER COLLECTED BETWEEN TOWERS -------------
 
-- waterCollected :: [Int] -> Int
Line 673:
return lst
end tell
end zipWith</langsyntaxhighlight>
{{Out}}
<langsyntaxhighlight AppleScriptlang="applescript">{2, 14, 35, 0, 0, 0, 0}</langsyntaxhighlight>
 
=={{header|Arturo}}==
 
<syntaxhighlight lang="arturo">cmax: function => [
m: neg ∞
map & 'x -> m:<=max @[m x]
]
 
vmin: $ => [map couple & & => min]
 
vsub: $ => [map couple & & 'p -> p\0 - p\1]
 
water: function [a][
sum vsub vmin reverse cmax reverse a cmax a a
]
 
loop [
[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]
] 'a -> print [a "->" water a]</syntaxhighlight>
 
{{out}}
 
<pre>[1 5 3 7 2] -> 2
[5 3 7 2 6 4 5 9 1 2] -> 14
[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|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">WCBT(oTwr){
topL := Max(oTwr*), l := num := 0, barCh := lbarCh := "", oLvl := []
while (++l <= topL)
Line 693 ⟶ 728:
}
return [num, barCh]
}</langsyntaxhighlight>
Examples:<langsyntaxhighlight AutoHotkeylang="autohotkey">data := [[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]
Line 711 ⟶ 746:
result .= "Chart " inp " has " x.1 " water units`n" x.2 "------------------------`n"
}
MsgBox % result</langsyntaxhighlight>
{{out}}
<pre>Chart [1, 5, 3, 7, 2] has 2 water units
Line 784 ⟶ 819:
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
<lang AWK>
# syntax: GAWK -f WATER_COLLECTED_BETWEEN_TOWERS.AWK [-v debug={0|1}]
BEGIN {
Line 816 ⟶ 851:
function max(x,y) { return((x > y) ? x : y) }
function min(x,y) { return((x < y) ? x : y) }
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 829 ⟶ 864:
 
=={{header|BASIC}}==
==={{header|FreeBASIC}}===
<lang BASIC>10 DEFINT A-Z: DIM T(20): K=0
Uses Nigel Galloway's very elegant idea, expressed verbosely so you can really see what's going on.
<syntaxhighlight lang="freebasic">type tower
hght as uinteger
posi as uinteger
end type
 
sub shellsort( a() as tower )
'quick and dirty shellsort, not the focus of this exercise
dim as uinteger gap = ubound(a), i, j, n=ubound(a)
dim as tower temp
do
gap = int(gap / 2.2)
if gap=0 then gap=1
for i=gap to n
temp = a(i)
j=i
while j>=gap andalso a(j-gap).hght < temp.hght
a(j) = a(j - gap)
j -= gap
wend
a(j) = temp
next i
loop until gap = 1
end sub
 
'heights of towers in each city prefixed by the number of towers
data 5, 1, 5, 3, 7, 2
data 10, 5, 3, 7, 2, 6, 4, 5, 9, 1, 2
data 16, 2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1
data 4, 5, 5, 5, 5
data 4, 5, 6, 7, 8
data 4, 8, 7, 7, 6
data 5, 6, 7, 10, 7, 6
 
dim as uinteger i, n, j, first, last, water
dim as tower manhattan(0 to 1)
for i = 1 to 7
read n
redim manhattan( 0 to n-1 )
for j = 0 to n-1
read manhattan(j).hght
manhattan(j).posi = j
next j
shellsort( manhattan() )
if manhattan(0).posi < manhattan(1).posi then
first = manhattan(0).posi
last = manhattan(1).posi
else
first = manhattan(1).posi
last = manhattan(0).posi
end if
water = manhattan(1).hght * (last-first-1)
for j = 2 to n-1
if first<manhattan(j).posi and manhattan(j).posi<last then water -= manhattan(j).hght
if manhattan(j).posi < first then
water += manhattan(j).hght * (first-manhattan(j).posi-1)
first = manhattan(j).posi
end if
if manhattan(j).posi > last then
water += manhattan(j).hght * (manhattan(j).posi-last-1)
last = manhattan(j).posi
end if
next j
print using "City configuration ## collected #### units of water."; i; water
next i</syntaxhighlight>
{{out}}
<pre>City configuration 1 collected 2 units of water.
City configuration 2 collected 14 units of water.
City configuration 3 collected 35 units of water.
City configuration 4 collected 0 units of water.
City configuration 5 collected 0 units of water.
City configuration 6 collected 0 units of water.
City configuration 7 collected 0 units of water.</pre>
 
==={{header|GW-BASIC}}===
{{works with|BASICA}}
<syntaxhighlight lang="gwbasic">10 DEFINT A-Z: DIM T(20): K=0
20 K=K+1: READ N: IF N=0 THEN END
30 FOR I=0 TO N-1: READ T(I): NEXT
Line 848 ⟶ 960:
180 DATA 4, 8,7,7,6
190 DATA 5, 6,7,10,7,6
200 DATA 0</langsyntaxhighlight>
{{out}}
<pre>Block 1 holds 2 water units.
Block 2 holds 14 water units.
Block 3 holds 35 water units.
Block 4 holds 0 water units.
Block 5 holds 0 water units.
Block 6 holds 0 water units.
Block 7 holds 0 water units.</pre>
 
 
==={{header|Nascom BASIC}}===
{{trans|FreeBasic}}
{{works with|Nascom ROM BASIC|4.7}}
<syntaxhighlight lang="basic">
10 REM Water collected between towers
20 MXN=19
30 REM Heights of towers in each city
40 REM prefixed by the number of towers
50 DATA 5,1,5,3,7,2
60 DATA 10,5,3,7,2,6,4,5,9,1,2
70 DATA 16,2,6,3,5,2,8,1,4,2,2,5,3,5,7,4,1
80 DATA 4,5,5,5,5
90 DATA 4,5,6,7,8
100 DATA 4,8,7,7,6
110 DATA 5,6,7,10,7,6
120 DIM A(MXN,1)
130 FOR I=1 TO 7
140 READ N
150 FOR J=0 TO N-1
160 READ A(J,0)
170 A(J,1)=J
180 NEXT J
190 GOSUB 390
200 IF A(0,1)>=A(1,1) THEN 220
210 FRST=A(0,1):LST=A(1,1):GOTO 230
220 FRST=A(1,1):LST=A(0,1)
230 WTR=A(1,0)*(LST-FRST-1)
240 FOR J=2 TO N-1
250 IF FRST>=A(J,1) OR A(J,1)>=LST THEN 270
260 WTR=WTR-A(J,0)
270 IF A(J,1)>=FRST THEN 300
280 WTR=WTR+A(J,0)*(FRST-A(J,1)-1)
290 FRST=A(J,1)
300 IF A(J,1)<=LST THEN 330
310 WTR=WTR+A(J,0)*(A(J,1)-LST-1)
320 LST=A(J,1)
330 NEXT J
340 PRINT "Bar chart";I;"collected";
350 PRINT WTR;"units of water."
360 NEXT I
370 END
380 REM ** ShellSort
390 GAP=N-1
400 GAP=INT(GAP/2.2)
410 IF GAP=0 THEN GAP=1
420 FOR K=GAP TO N-1
430 TH=A(K,0):TP=A(K,1)
440 L=K
450 IF L<GAP THEN 500
460 IF A(L-GAP,0)>=TH THEN 500
470 A(L,0)=A(L-GAP,0):A(L,1)=A(L-GAP,1)
480 L=L-GAP
490 GOTO 450
500 A(L,0)=TH:A(L,1)=TP
510 NEXT K
520 IF GAP<>1 THEN 400
530 RETURN
</syntaxhighlight>
{{out}}
<pre>
Bar chart 1 collected 2 units of water.
Bar chart 2 collected 14 units of water.
Bar chart 3 collected 35 units of water.
Bar chart 4 collected 0 units of water.
Bar chart 5 collected 0 units of water.
Bar chart 6 collected 0 units of water.
Bar chart 7 collected 0 units of water.
</pre>
 
==={{header|QuickBASIC}}===
{{trans|FreeBasic}}
<syntaxhighlight lang="qbasic">
' Water collected between towers
DECLARE SUB ShellSort (A() AS ANY)
TYPE TTowerRec
Hght AS INTEGER
Posi AS INTEGER
END TYPE
 
'heights of towers in each city prefixed by the number of towers
DATA 5, 1, 5, 3, 7, 2
DATA 10, 5, 3, 7, 2, 6, 4, 5, 9, 1, 2
DATA 16, 2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1
DATA 4, 5, 5, 5, 5
DATA 4, 5, 6, 7, 8
DATA 4, 8, 7, 7, 6
DATA 5, 6, 7, 10, 7, 6
 
REM $DYNAMIC
DIM Manhattan(0 TO 1) AS TTowerRec
FOR I% = 1 TO 7
READ N%
ERASE Manhattan
REDIM Manhattan(0 TO N% - 1) AS TTowerRec
FOR J% = 0 TO N% - 1
READ Manhattan(J%).Hght
Manhattan(J%).Posi = J%
NEXT J%
ShellSort Manhattan()
IF Manhattan(0).Posi < Manhattan(1).Posi THEN
First% = Manhattan(0).Posi
Last% = Manhattan(1).Posi
ELSE
First% = Manhattan(1).Posi
Last% = Manhattan(0).Posi
END IF
Water% = Manhattan(1).Hght * (Last% - First% - 1)
FOR J% = 2 TO N% - 1
IF First% < Manhattan(J%).Posi AND Manhattan(J%).Posi < Last% THEN Water% = Water% - Manhattan(J%).Hght
IF Manhattan(J%).Posi < First% THEN
Water% = Water% + Manhattan(J%).Hght * (First% - Manhattan(J%).Posi - 1)
First% = Manhattan(J%).Posi
END IF
IF Manhattan(J%).Posi > Last% THEN
Water% = Water% + Manhattan(J%).Hght * (Manhattan(J%).Posi - Last% - 1)
Last% = Manhattan(J%).Posi
END IF
NEXT J%
PRINT USING "City configuration ## collected #### units of water."; I%; Water%
NEXT I%
END
 
REM $STATIC
SUB ShellSort (A() AS TTowerRec)
'quick and dirty shellsort, not the focus of this exercise
Gap% = UBOUND(A): N% = UBOUND(A)
DIM Temp AS TTowerRec
DO
Gap% = INT(Gap% / 2.2)
IF Gap% = 0 THEN Gap% = 1
FOR I% = Gap% TO N%
Temp = A(I%)
J% = I%
' Simulated WHILE J% >= Gap% ANDALSO A(J% - Gap%).Hght < Temp.Hght
DO
IF J% < Gap% THEN EXIT DO
IF A(J% - Gap%).Hght >= Temp.Hght THEN EXIT DO
A(J%) = A(J% - Gap%)
J% = J% - Gap%
LOOP
A(J%) = Temp
NEXT I%
LOOP UNTIL Gap% = 1
END SUB
</syntaxhighlight>
{{out}}
<pre>
City configuration 1 collected 2 units of water.
City configuration 2 collected 14 units of water.
City configuration 3 collected 35 units of water.
City configuration 4 collected 0 units of water.
City configuration 5 collected 0 units of water.
City configuration 6 collected 0 units of water.
City configuration 7 collected 0 units of water.
</pre>
 
==={{header|uBasic/4tH}}===
{{Trans|GW-BASIC}}
<syntaxhighlight lang="basic">Dim @t(20)
 
k = FUNC (_getWater (1, 5, 3, 7, 2, 1))
k = FUNC (_getWater (5, 3, 7, 2, 6, 4, 5, 9, 1, 2, k))
k = FUNC (_getWater (2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1, k))
k = FUNC (_getWater (5, 5, 5, 5, k))
k = FUNC (_getWater (5, 6, 7, 8, k))
k = FUNC (_getWater (8, 7, 7, 6, k))
k = FUNC (_getWater (6, 7, 10, 7, 6, k))
End
 
_getWater
Param (1)
Local (2)
 
w = 0
c@ = Used()
 
For b@ = c@ - 1 To 0 Step -1
@t(b@) = Pop()
Next
 
Do While FUNC(_netWater (c@)) > 1 : Loop
 
Print "Block ";a@;" holds ";w;" water units."
Return (a@ + 1)
 
_netWater
Param (1)
Local (3)
 
For d@ = a@-1 To 0 Step -1
If @t(d@) Then
If d@ = 0 Then Unloop : Return (0) : fi
Else
Continue
EndIf
 
b@ = 0
 
For c@ = 0 To d@
If @t(c@) > 0 Then
@t(c@) = @t(c@) - 1
b@ = b@ + 1
Else
If b@ > 0 Then w = w + 1 : fi
EndIf
Next
 
Unloop : Return (b@)
Next
Return (0)</syntaxhighlight>
{{Out}}
<pre>Block 1 holds 2 water units.
Block 2 holds 14 water units.
Line 858 ⟶ 1,188:
Block 5 holds 0 water units.
Block 6 holds 0 water units.
Block 7 holds 0 water units.</pre>
 
0 OK, 0:409</pre>
 
==={{header|Visual Basic .NET}}===
====Version 1====
'''Method:''' Instead of "scanning" adjoining towers for each column, this routine converts the tower data into a string representation with building blocks, empty spaces, and potential water retention sites. The potential water retention sites are then "eroded" away where they are found to be unsupported. This is accomplished with the '''.Replace()''' function. The replace operations are unleashed upon the entire "block" of towers, rather than a cell at a time or a line at a time - which perhaps increases the program's execution-time, but reduces program's complexity.
 
The program can optionally display the interim string representation of each tower block before the final count is completed. I've since modified it to have the same block and wavy characters are the
[[{{FULLPAGENAME}}#version_3|REXX 9.3]] output, but used the double-wide columns, as pictured in the task definition area.
<syntaxhighlight lang="vbnet">' Convert tower block data into a string representation, then manipulate that.
Module Module1
Sub Main(Args() As String)
Dim shoTow As Boolean = Environment.GetCommandLineArgs().Count > 1 ' Show towers.
Dim wta As Integer()() = { ' Water tower array (input data).
New Integer() {1, 5, 3, 7, 2}, New Integer() {5, 3, 7, 2, 6, 4, 5, 9, 1, 2},
New Integer() {2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1},
New Integer() {5, 5, 5, 5}, New Integer() {5, 6, 7, 8},
New Integer() {8, 7, 7, 6}, New Integer() {6, 7, 10, 7, 6}}
Dim blk As String, ' String representation of a block of towers.
lf As String = vbLf, ' Line feed to separate floors in a block of towers.
tb = "██", wr = "≈≈", mt = " " ' Tower Block, Water Retained, eMpTy space.
For i As Integer = 0 To wta.Length - 1
Dim bpf As Integer ' Count of tower blocks found per floor.
blk = ""
Do
bpf = 0 : Dim floor As String = "" ' String representation of each floor.
For j As Integer = 0 To wta(i).Length - 1
If wta(i)(j) > 0 Then ' Tower block detected, add block to floor,
floor &= tb : wta(i)(j) -= 1 : bpf += 1 ' reduce tower by one.
Else ' Empty space detected, fill when not first or last column.
floor &= If(j > 0 AndAlso j < wta(i).Length - 1, wr, mt)
End If
Next
If bpf > 0 Then blk = floor & lf & blk ' Add floors until blocks are gone.
Loop Until bpf = 0 ' No tower blocks left, so terminate.
' Erode potential water retention cells from left and right.
While blk.Contains(mt & wr) : blk = blk.Replace(mt & wr, mt & mt) : End While
While blk.Contains(wr & mt) : blk = blk.Replace(wr & mt, mt & mt) : End While
' Optionaly show towers w/ water marks.
If shoTow Then Console.Write("{0}{1}", lf, blk)
' Subtract the amount of non-water mark characters from the total char amount.
Console.Write("Block {0} retains {1,2} water units.{2}", i + 1,
(blk.Length - blk.Replace(wr, "").Length) \ 2, lf)
Next
End Sub
End Module</syntaxhighlight>
{{out}}<syntaxhighlight lang="text">Block 1 retains 2 water units.
Block 2 retains 14 water units.
Block 3 retains 35 water units.
Block 4 retains 0 water units.
Block 5 retains 0 water units.
Block 6 retains 0 water units.
Block 7 retains 0 water units.</syntaxhighlight>
Verbose output shows towers with water ("Almost equal to" characters) left in the "wells" between towers. Just supply any command-line parameter to see it. Use no command line parameters to see the plain output above.
<syntaxhighlight lang="text"> ██
██
██≈≈██
██≈≈██
██████
████████
██████████
Block 1 retains 2 water units.
 
██
██
██≈≈≈≈≈≈≈≈██
██≈≈██≈≈≈≈██
██≈≈██≈≈██≈≈████
██≈≈██≈≈████████
██████≈≈████████
████████████████≈≈██
████████████████████
Block 2 retains 14 water units.
 
██
██≈≈≈≈≈≈≈≈≈≈≈≈≈≈██
██≈≈≈≈≈≈██≈≈≈≈≈≈≈≈≈≈≈≈≈≈██
██≈≈██≈≈██≈≈≈≈≈≈≈≈██≈≈████
██≈≈██≈≈██≈≈██≈≈≈≈██≈≈██████
██████≈≈██≈≈██≈≈≈≈██████████
████████████≈≈████████████████
████████████████████████████████
Block 3 retains 35 water units.
 
████████
████████
████████
████████
████████
Block 4 retains 0 water units.
 
██
████
██████
████████
████████
████████
████████
████████
Block 5 retains 0 water units.
 
██
██████
████████
████████
████████
████████
████████
████████
Block 6 retains 0 water units.
 
██
██
██
██████
██████████
██████████
██████████
██████████
██████████
██████████
Block 7 retains 0 water units.</syntaxhighlight>
 
====Version 2====
'''Method:''' More conventional "scanning" method. A Char array is used, but no Replace() statements. Output is similar to version 1, although there is now a left margin of three spaces, the results statement is immediately to the right of the string representation of the tower blocks (instead of underneath), the verb is "hold(s)" instead of "retains", and there is a special string when the results indicate zero.
 
<syntaxhighlight lang="vbnet">Module Module1
''' <summary>
''' wide - Widens the aspect ratio of a linefeed separated string.
''' </summary>
''' <param name="src">A string representing a block of towers.</param>
''' <param name="margin">Optional padding for area to the left.</param>
''' <returns>A double-wide version of the string.</returns>
Function wide(src As String, Optional margin As String = "") As String
Dim res As String = margin : For Each ch As Char In src
res += If(ch < " ", ch & margin, ch + ch) : Next : Return res
End Function
 
''' <summary>
''' cntChar - Counts characters, also custom formats the output.
''' </summary>
''' <param name="src">The string to count characters in.</param>
''' <param name="ch">The character to be counted.</param>
''' <param name="verb">Verb to include in format. Expecting "hold",
''' but can work with "retain" or "have".</param>
''' <returns>The count of chars found in a string, and formats a verb.</returns>
Function cntChar(src As String, ch As Char, verb As String) As String
Dim cnt As Integer = 0
For Each c As Char In src : cnt += If(c = ch, 1, 0) : Next
Return If(cnt = 0, "does not " & verb & " any",
verb.Substring(0, If(verb = "have", 2, 4)) & "s " & cnt.ToString())
End Function
 
''' <summary>
''' report - Produces a report of the number of rain units found in
''' a block of towers, optionally showing the towers.
''' Autoincrements the blkID for each report.
''' </summary>
''' <param name="tea">An int array with tower elevations.</param>
''' <param name="blkID">An int of the block of towers ID.</param>
''' <param name="verb">The verb to use in the description.
''' Defaults to "has / have".</param>
''' <param name="showIt">When true, the report includes a string representation
''' of the block of towers.</param>
''' <returns>A string containing the amount of rain units, optionally preceeded by
''' a string representation of the towers holding any water.</returns>
Function report(tea As Integer(), ' Tower elevation array.
ByRef blkID As Integer, ' Block ID for the description.
Optional verb As String = "have", ' Verb to use in the description.
Optional showIt As Boolean = False) As String ' Show representaion.
Dim block As String = "", ' The block of towers.
lf As String = vbLf, ' The separator between floors.
rTwrPos As Integer ' The position of the rightmost tower of this floor.
Do
For rTwrPos = tea.Length - 1 To 0 Step -1 ' Determine the rightmost tower
If tea(rTwrPos) > 0 Then Exit For ' postition on this floor.
Next
If rTwrPos < 0 Then Exit Do ' When no towers remain, exit the do loop.
' init the floor to a space filled Char array, as wide as the block of towers.
Dim floor As Char() = New String(" ", tea.Length).ToCharArray()
Dim bpf As Integer = 0 ' The count of blocks found per floor.
For column As Integer = 0 To rTwrPos ' Scan from left to right.
If tea(column) > 0 Then ' If a tower exists here,
floor(column) = "█" ' mark the floor with a block,
tea(column) -= 1 ' drop the tower elevation by one,
bpf += 1 ' and advance the block count.
ElseIf bpf > 0 Then ' Otherwise, see if a tower is present to the left.
floor(column) = "≈" ' OK to fill with water.
End If
Next
If bpf > If(showIt, 0, 1) Then ' Continue the building only when needed.
' If not showing blocks, discontinue building when a single tower remains.
' build tower blocks string with each floor added to top.
block = New String(floor) & If(block = "", "", lf) & block
Else
Exit Do ' Ran out of towers, so exit the do loop.
End If
Loop While True ' Depending on previous break statements to terminate the do loop.
blkID += 1 ' increment block ID counter.
' format report and return it.
Return If(showIt, String.Format(vbLf & "{0}", wide(block, " ")), "") &
String.Format(" Block {0} {1} water units.", blkID, cntChar(block, "≈", verb))
End Function
 
''' <summary>
''' Main routine.
'''
''' With one command line parameter, it shows tower blocks,
''' with no command line parameters, it shows a plain report
'''</summary>
Sub Main()
Dim shoTow As Boolean = Environment.GetCommandLineArgs().Count > 1 ' Show towers.
Dim blkCntr As Integer = 0 ' Block ID for reports.
Dim verb As String = "hold" ' "retain" or "have" can be used instead of "hold".
Dim tea As Integer()() = {New Integer() {1, 5, 3, 7, 2}, ' Tower elevation data.
New Integer() {5, 3, 7, 2, 6, 4, 5, 9, 1, 2},
New Integer() {2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1},
New Integer() {5, 5, 5, 5}, New Integer() {5, 6, 7, 8},
New Integer() {8, 7, 7, 6}, New Integer() {6, 7, 10, 7, 6}}
For Each block As Integer() In tea
' Produce report for each block of towers.
Console.WriteLine(report(block, blkCntr, verb, shoTow))
Next
End Sub
End Module</syntaxhighlight>
Regular version 2 output:
<syntaxhighlight lang="text"> Block 1 holds 2 water units.
Block 2 holds 14 water units.
Block 3 holds 35 water units.
Block 4 does not hold any water units.
Block 5 does not hold any water units.
Block 6 does not hold any water units.
Block 7 does not hold any water units.</syntaxhighlight>
Sample of version 2 verbose output:
<syntaxhighlight lang="text"> ██
██≈≈≈≈≈≈≈≈≈≈≈≈≈≈██
██≈≈≈≈≈≈██≈≈≈≈≈≈≈≈≈≈≈≈≈≈██
██≈≈██≈≈██≈≈≈≈≈≈≈≈██≈≈████
██≈≈██≈≈██≈≈██≈≈≈≈██≈≈██████
██████≈≈██≈≈██≈≈≈≈██████████
████████████≈≈████████████████
████████████████████████████████ Block 3 holds 35 water units.
 
████████
████████
████████
████████
████████ Block 4 does not hold any water units.</syntaxhighlight>
 
==={{header|Yabasic}}===
{{trans|AWK}}
<syntaxhighlight lang="yabasic">data 7
data "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"
data "5,5,5,5", "5,6,7,8", "8,7,7,6", "6,7,10,7,6"
 
read n
 
for i = 1 to n
read n$
wcbt(n$)
next i
 
sub wcbt(s$)
local tower$(1), hr(1), hl(1), n, i, ans, k
n = token(s$, tower$(), ",")
 
redim hr(n)
redim hl(n)
for i = n to 1 step -1
if i < n then
k = hr(i + 1)
else
k = 0
end if
hr(i) = max(val(tower$(i)), k)
next i
for i = 1 to n
if i then
k = hl(i - 1)
else
k = 0
end if
hl(i) = max(val(tower$(i)), k)
ans = ans + min(hl(i), hr(i)) - val(tower$(i))
next i
print ans," ",n$
end sub</syntaxhighlight>
 
=={{header|C}}==
Takes the integers as input from command line, prints out usage on incorrect invocation.
<syntaxhighlight lang="c">
<lang C>
#include<stdlib.h>
#include<stdio.h>
Line 934 ⟶ 1,552:
return 0;
}
</syntaxhighlight>
</lang>
Output :
<pre>
Line 954 ⟶ 1,572:
===Version 1===
Translation from [[{{FULLPAGENAME}}#Visual_Basic_.NET|Visual Basic .NET]]. See that version 1 entry for code comment details and more sample output.
<langsyntaxhighlight Csharplang="csharp">class Program
{
static void Main(string[] args)
Line 983 ⟶ 1,601:
}
}
}</langsyntaxhighlight>{{out}}<syntaxhighlight lang="text">Block 1 retains 2 water units.
Block 2 retains 14 water units.
Block 3 retains 35 water units.
Line 989 ⟶ 1,607:
Block 5 retains 0 water units.
Block 6 retains 0 water units.
Block 7 retains 0 water units.</langsyntaxhighlight>
===Version 2===
Conventional "scanning" algorithm, translated from [[{{FULLPAGENAME}}#Version_2_2|the second version of Visual Basic.NET]], but (intentionally tweaked to be) incapable of verbose output. See that version 2 entry for code comments and details.
<langsyntaxhighlight cSharplang="csharp">class Program
{
// Variable names key:
Line 1,028 ⟶ 1,646:
}
}
}</langsyntaxhighlight>
'''Output:'''
<pre>Block 1 holds 2 water units.
Line 1,039 ⟶ 1,657:
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">
#include <iostream>
#include <vector>
Line 1,103 ⟶ 1,721:
std::cin.get();
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 1,117 ⟶ 1,735:
Similar two passes algorithm as many solutions here. First traverse left to right to find the highest tower on the left of each position, inclusive of the tower at the current position, than do the same to find the highest tower to the right of each position. Finally, compute the total water units held at any position as the difference of those two heights.
 
<langsyntaxhighlight lang="clojure">
(defn trapped-water [towers]
(let [maxes #(reductions max %) ; the seq of increasing max values found in the input seq
Line 1,124 ⟶ 1,742:
mins (map min maxl maxr)] ; minimum highest surrounding tower per position
(reduce + (map - mins towers)))) ; sum up the trapped water per position
</syntaxhighlight>
</lang>
{{out}}
<langsyntaxhighlight lang="clojure">
;; in the following, # is a tower block and ~ is trapped water:
;;
Line 1,142 ⟶ 1,760:
;; 5 3 7 2 6 4 5 9 1 2
(trapped-water [5 3 7 2 6 4 5 9 1 2]) ;; 14
</syntaxhighlight>
</lang>
 
=={{header|CLU}}==
<langsyntaxhighlight lang="clu">max = proc [T: type] (a,b: T) returns (T)
where T has lt: proctype (T,T) returns (bool)
if a<b then return(b)
Line 1,195 ⟶ 1,813:
stream$puts(po, int$unparse(water(test)) || " ")
end
end start_up</langsyntaxhighlight>
{{out}}
<pre>2 14 35 0 0 0 0</pre>
 
=={{header|Cowgol}}==
<langsyntaxhighlight lang="cowgol">include "cowgol.coh";
include "argv.coh";
 
Line 1,254 ⟶ 1,872:
 
print_i8(water(&towers[0], count as intptr));
print_nl();</langsyntaxhighlight>
 
{{out}}
Line 1,275 ⟶ 1,893:
=={{header|D}}==
{{Trans|C#}}
<langsyntaxhighlight Dlang="d">import std.stdio;
 
void main() {
Line 1,323 ⟶ 1,941:
writeln(" water units.");
}
}</langsyntaxhighlight>
 
{{out}}
Line 1,333 ⟶ 1,951:
Block 6 does not hold any water units.
Block 7 does not hold any water units.</pre>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
The program builds a matrix of the towers and scans each line looking for pairs of towers that trap water.
 
<syntaxhighlight lang="Delphi">
 
var Towers1: array [0..4] of integer = (1, 5, 3, 7, 2);
var Towers2: array [0..9] of integer = (5, 3, 7, 2, 6, 4, 5, 9, 1, 2);
var Towers3: array [0..15] of integer = (2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1);
var Towers4: array [0..3] of integer = (5, 5, 5, 5);
var Towers5: array [0..3] of integer = (5, 6, 7, 8);
var Towers6: array [0..3] of integer = (8, 7, 7, 6);
var Towers7: array [0..4] of integer = (6, 7, 10, 7, 6);
 
 
type TMatrix = array of array of boolean;
 
function ArrayToMatrix(Towers: array of integer): TMatrix;
{Convert Tower Array to Matrix for analysis}
var Max,I,X,Y: integer;
begin
Max:=0;
for I:=0 to High(Towers) do if Towers[I]>=Max then Max:=Towers[I];
SetLength(Result,Length(Towers),Max);
for Y:=0 to High(Result[0]) do
for X:=0 to High(Result) do Result[X,Y]:=Towers[X]>(Max-Y);
end;
 
 
procedure DisplayMatrix(Memo: TMemo; Matrix: TMatrix);
{Display a matrix}
var X,Y: integer;
var S: string;
begin
for Y:=0 to High(Matrix[0]) do
begin
S:='[';
for X:=0 to High(Matrix) do
begin
if Matrix[X,Y] then S:=S+'#'
else S:=S+' ';
end;
S:=S+']';
Memo.Lines.Add(S);
end;
end;
 
 
function GetWaterStorage(Matrix: TMatrix): integer;
{Analyze matrix to get water storage amount}
var X,Y,Cnt: integer;
var Inside: boolean;
begin
Result:=0;
{Scan each row of matrix to see if it is storing water}
for Y:=0 to High(Matrix[0]) do
begin
Inside:=False;
Cnt:=0;
for X:=0 to High(Matrix) do
begin
{Test if this is a tower}
if Matrix[X,Y] then
begin
{if so, we may be inside trough}
Inside:=True;
{If Cnt>0 there was a previous tower}
{And we've impounded water }
Result:=Result+Cnt;
{Start new count with new tower}
Cnt:=0;
end
else if Inside then Inc(Cnt); {Count potential impounded water}
end;
end;
end;
 
 
procedure ShowWaterLevels(Memo: TMemo; Towers: array of integer);
{Analyze the water storage of towers and display result}
var Water: integer;
var Matrix: TMatrix;
begin
Matrix:=ArrayToMatrix(Towers);
DisplayMatrix(Memo,Matrix);
Water:=GetWaterStorage(Matrix);
Memo.Lines.Add('Storage: '+IntToStr(Water)+CRLF);
end;
 
 
procedure WaterLevel(Memo: TMemo);
begin
ShowWaterLevels(Memo,Towers1);
ShowWaterLevels(Memo,Towers2);
ShowWaterLevels(Memo,Towers3);
ShowWaterLevels(Memo,Towers4);
ShowWaterLevels(Memo,Towers5);
ShowWaterLevels(Memo,Towers6);
ShowWaterLevels(Memo,Towers7);
end;
 
 
 
 
</syntaxhighlight>
{{out}}
<pre>
[ ]
[ # ]
[ # ]
[ # # ]
[ # # ]
[ ### ]
[ ####]
Storage: 2
 
[ ]
[ # ]
[ # ]
[ # # ]
[ # # # ]
[# # # ## ]
[# # #### ]
[### #### ]
[######## #]
Storage: 14
 
[ ]
[ # ]
[ # # ]
[ # # # ]
[ # # # # ## ]
[ # # # # # ### ]
[ ### # # ##### ]
[###### ######## ]
Storage: 35
 
[ ]
[####]
[####]
[####]
[####]
Storage: 0
 
[ ]
[ #]
[ ##]
[ ###]
[####]
[####]
[####]
[####]
Storage: 0
 
[ ]
[# ]
[### ]
[####]
[####]
[####]
[####]
[####]
Storage: 0
 
[ ]
[ # ]
[ # ]
[ # ]
[ ### ]
[#####]
[#####]
[#####]
[#####]
[#####]
Storage: 0
 
 
Elapsed Time: 171.444 ms.
 
</pre>
 
=={{header|EasyLang}}==
 
<syntaxhighlight lang="easylang">
proc water h[] . .
n = len h[]
len left[] n
len right[] n
for i = 1 to n
max = higher max h[i]
left[i] = max
.
max = 0
for i = n downto 1
max = higher max h[i]
right[i] = max
.
for i = 1 to n
sum += (lower left[i] right[i]) - h[i]
.
print sum
.
repeat
s$ = input
until s$ = ""
water number strsplit s$ " "
.
#
input_data
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
 
</syntaxhighlight>
 
=={{header|EDSAC order code}}==
Uses the same algorithm as the Pascal solution.
<syntaxhighlight lang="edsac">
[Water collected between towers - Rosetta Code
For EDSAC, Initial Orders 2.]
 
[Arrange the storage]
T45K P100F [H parameter: library subroutine R4 to read integer]
T46K P200F [N parameter: modified library s/r P7 to print integer]
T47K P300F [M parameter: main routine]
T48K P900F [& (delta) parameter: store for array of heights]
T49K P400F [L parameter: subroutine to calculate amount of water]
[-----------------------------------------------------------------------
Subroutine to calculate amount of water as a 35-bit integer.
Heights are in an array of 35-bit integers, preceded by a count of heights.
For convenience, the count is also a 35-bit integer, though with the small
amount of storage on EDSAC it can't be more than a few hundred.
Input: Address of count follows subroutine call.
Output: 0D = result.
Workspace: 4D]
E25K TL GK
A89@ U88@ [plant return link, allowing for A parameter after call]
S90@ T4@ [form and plant order to read address of count]
[4] AF [(planted) read address of count]
A91@ U15@ [form and plant order to read count as 35-bit]
A92@ U26@ [form and plant order to read h{0}]
U32@ U43@ U93@ [plant in 3 more places]
A92@ T49@ [form and plant order to read h{1}]
TD [build result in 0D; initialize to 0]
[15] AD [(planted) acc := 35-bit count of towers]
T4D A4F [convert count to 17-bit]
L1F [shift 2 left, to get 2*count in address field]
A15@ U65@ [form and plant order to read h{n-1}]
S92@ U71@ [same for h{n-2}]
S49@ [acc := 2*(n - 3) in address field]
G87@ [if < 3 towers, exit with result = 0]
T4F [clear acc]
[26] AD [acc := h{0}]
T94#@ [initialize maximum height]
[Find height and position of highest tower (position in terms of A order).
Note: Since EDSAC had only 2 conditional jumps (acc < 0 and acc >= 0),
it's simplest to update the maximum when h{i} >= max (not h{i} > max).]
[28] T4F [clear acc]
A32@ A92@ T32@ [inc array index: first time 0 --> 1]
[32] AD S94#@ [acc := h{i} - (current maximum)]
G39@ [skip if h{i} < max]
A94#@ [restore acc after test]
T94#@ [update value of maximum]
A32@ T93@ [update A order for maximum]
[39] T4F [clear acc]
A32@ S65@ [have we just done h{n-1}?]
G28@ [loop back if not]
[Fill troughs from the left. Here with acc = 0.]
[43] AD [(planted) read h{0}]
T94#@ [initialize level to h{0}]
A49@ [acc := A order for h{1}]
S93@ [subtract A order for maximum]
E64@ [skip if maximum is at h{0} or h{1}]
[Start of loop]
[48] T4F [clear acc]
[49] AD [read h{i}; initially i = 1]
S94#@ [subtract current level]
G55@ [skip if h{i} < level]
A94#@ [restore acc after test]
T94#@ [update level]
E59@ [join common code]
[55] T4D [temp store h{i} - h_max, which is < 0]
AD [acc := result so far]
S4D [add h_max - h{i} to result]
TD [update result]
[59] A49@ A92@ U49@ [make A order for h{i+1}]
S93@ [have we reached the highest tower yet?]
G48@ [if not, loop back]
[Fill troughs from the right.
Similar to filling from the left, so given in condensed form to save space.]
[64] T4F
[65] AF T94#@ A93@ S71@ E87@
[70] T4F
[71] AF S94#@ G77@ A94#@ T94#@ E81@
[77] T4D AD S4D TD
[81] A71@ S92@ T71@ A93@ S71@ G70@
[Exit from suubroutine]
[87] T4F [clear acc on exit, as usual]
[88] ZF [(planted) jump back to caller]
[Constants]
[89] U3F
[90] U1F [subtract to convert E order to A order]
[91] AD
[92] P2F [2 in address field]
[Variables: Swap if necessary to get 35-bit variable at even address]
[93] AF [order to read h_max]
[94] PF PF [current maximum height]
[-----------------------------------------------------------------------]
[Main routine: must be at even address]
E25K TM GK
[0] PF PF [store for 35-bit height]
[2] PF [data count]
[3] P2F [to change address by 2]
[4] #F [figure shift]
[5] K2048F [letter shift]
[6] DF[7] IF[8] YF
[9] NF [comma (in figures mode)]
[10] @F [carriage return]
[11] &F [line feed]
[12] !F [space]
[13] K4096F [teleprinter null]
[Entry]
[14] O4@ [set figures]
[Loop over datasets]
[15] A15@ GH [call library subroutine R4, sets 0D := data count N]
SD E63@ [exit if N = 0]
T4F [clear acc]
A23@ T40@ [initialize T order to store data]
AD [load data count, 35-bit but with high half = 0]
[23] T#& [store at start of data]
[24] S& [acc := 17-bit negative count of data]
[25] LD [shift to address field *** or use k1 to inc ?? ***]
G28@ [don't print comma before first height]
[Loop over heights in current dataset]
[27] O9@ [print comma]
[28] T2@ [update negative loop counter]
A40@ A3@ T40@ [inc address for next 35-bit height]
A32@ GH [read next height to 0D (clears acc)]
AD T#@ [acc := height, save locally]
A36@ GN !1F [print height, min width = 1]
A#@ [retrieve height]
[40] TD [(planted) store height in array]
A2@ A2F [inc negative loop counter]
G27@ [if not yet 0, loop back]
A44@ GL P& [call subroutine returns amount of water in 0D]
[Print ' YIELDS ' (requires temporary change to letters shift)]
O5@ O12@ O8@ O7@ O62@
O25@ O6@ O24@ O12@ O4@
A57@ GN !1F [print result, min width = 1; leaves acc = 0]
O10@ O11@ [print CR, LF]
[62] E15@ [loop back for next data set (also letter E)]
[Jump to here if data count = 0, means end of data]
[63] O13@ [print null to flush teleprinter buffer]
ZF [stop the machine]
[-------------------------------------------------------------------------------
Library subroutine R4.
Input of one signed integer, returned in 0D.]
E25K TH
GK A3F T21@ T4D H6@ E11@ P5D JF T6F VD L4F A4D TD I4F A4F S5@ G7@ S5@ G20@ SD TD T6F EF
[-------------------------------------------------------------------------------
Modification of library subroutine P7; prints integer N in range 0 <= N < 10^10.
Prints 0 correctly, and allows caller to specify a minimum width.
Input : 0D = integer (not preserved)
17-bit print control word follows subroutine call,
e.g. !5F means minimum width 5, pad on left with space.
49 locations; even address; workspace: 0F, 1F, 4D, 6F, 7F]
E25K TN
GK A48@ U4@ A27@ T35@ AF U4@ L256F S45@ T7F H46#@ ND YF LD T4D S45@ T1F H21@ S21@ A45@ G21@ U4@ TF V4D A1F G36@ S1F LD U1F O1F F1F S1F L4F T4D AF G18@ ZF S1F L8F T4D AF A7F G43@ O4@ T6F E33@ T46#Z PF T45Z P1024F P610D @524D P2F
[--------------------------------------------------------------------------------]
[M parameter (main routine) again]
E25K TM GK
E14Z [define entry point]
PF [acc = 0 on entry]
[--------------------------------------------------------------------------------]
[Counts and data values to be read by library subroutine R4.
Note sign comes _after_ value.]
5+ 1+5+3+7+2+
10+ 5+3+7+2+6+4+5+9+1+2+
16+ 2+6+3+5+2+8+1+4+2+2+5+3+5+7+4+1+
4+ 5+5+5+5+
4+ 5+6+7+8+
4+ 8+7+7+6+
5+ 6+7+10+7+6+
0+
</syntaxhighlight>
{{out}}
<pre>
1,5,3,7,2 YIELDS 2
5,3,7,2,6,4,5,9,1,2 YIELDS 14
2,6,3,5,2,8,1,4,2,2,5,3,5,7,4,1 YIELDS 35
5,5,5,5 YIELDS 0
5,6,7,8 YIELDS 0
8,7,7,6 YIELDS 0
6,7,10,7,6 YIELDS 0
</pre>
 
=={{header|Erlang}}==
Implements a version that uses recursion to solve the problem functionally, using two passes without requiring list reversal or modifications. On the list iteration from head to tail, gather the largest element seen so far (being the highest one on the left). Once the list is scanned, each position returns the highest tower to its right as reported by its follower, along with the amount of water seen so far, which can then be used to calculate the value at the current position. Back at the first list element, the final result is gathered.
 
<langsyntaxhighlight lang="erlang">
-module(watertowers).
-export([towers/1, demo/0]).
Line 1,359 ⟶ 2,378:
[io:format("~p -> ~p~n", [Case, towers(Case)]) || Case <- Cases],
ok.
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,376 ⟶ 2,395:
=={{header|F_Sharp|F#}}==
see http://stackoverflow.com/questions/24414700/water-collected-between-towers/43779936#43779936 for an explanation of this code. It is proportional to the number of towers. Although the examples on stackoverflow claim this, the n they use is actually the distance between the two end towers and not the number of towers. Consider the case of a tower of height 5 at 1, a tower of height 10 at 39, and a tower of height 3 at 101.
<langsyntaxhighlight lang="fsharp">
(*
A solution I'd show to Euclid !!!!.
Line 1,390 ⟶ 2,409:
| _ -> l
fn (min n i) (max n i) g (e*(abs(n-i)-1))
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,404 ⟶ 2,423:
 
=={{header|Factor}}==
<langsyntaxhighlight lang="factor">USING: formatting kernel math.statistics math.vectors sequences ;
 
: area ( seq -- n )
Line 1,417 ⟶ 2,436:
{ 8 7 7 6 }
{ 6 7 10 7 6 }
} [ dup area "%[%d, %] -> %d\n" printf ] each</langsyntaxhighlight>
{{out}}
<pre>
Line 1,428 ⟶ 2,447:
{ 6, 7, 10, 7, 6 } -> 0
</pre>
 
=={{header|FreeBASIC}}==
Uses Nigel Galloway's very elegant idea, expressed verbosely so you can really see what's going on.
<lang freebasic>type tower
hght as uinteger
posi as uinteger
end type
 
sub shellsort( a() as tower )
'quick and dirty shellsort, not the focus of this exercise
dim as uinteger gap = ubound(a), i, j, n=ubound(a)
dim as tower temp
do
gap = int(gap / 2.2)
if gap=0 then gap=1
for i=gap to n
temp = a(i)
j=i
while j>=gap andalso a(j-gap).hght < temp.hght
a(j) = a(j - gap)
j -= gap
wend
a(j) = temp
next i
loop until gap = 1
end sub
 
'heights of towers in each city prefixed by the number of towers
data 5, 1, 5, 3, 7, 2
data 10, 5, 3, 7, 2, 6, 4, 5, 9, 1, 2
data 16, 2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1
data 4, 5, 5, 5, 5
data 4, 5, 6, 7, 8
data 4, 8, 7, 7, 6
data 5, 6, 7, 10, 7, 6
 
dim as uinteger i, n, j, first, last, water
dim as tower manhattan(0 to 1)
for i = 1 to 7
read n
redim manhattan( 0 to n-1 )
for j = 0 to n-1
read manhattan(j).hght
manhattan(j).posi = j
next j
shellsort( manhattan() )
if manhattan(0).posi < manhattan(1).posi then
first = manhattan(0).posi
last = manhattan(1).posi
else
first = manhattan(1).posi
last = manhattan(0).posi
end if
water = manhattan(1).hght * (last-first-1)
for j = 2 to n-1
if first<manhattan(j).posi and manhattan(j).posi<last then water -= manhattan(j).hght
if manhattan(j).posi < first then
water += manhattan(j).hght * (first-manhattan(j).posi-1)
first = manhattan(j).posi
end if
if manhattan(j).posi > last then
water += manhattan(j).hght * (manhattan(j).posi-last-1)
last = manhattan(j).posi
end if
next j
print using "City configuration ## collected #### units of water."; i; water
next i</lang>
{{out}}
<pre>City configuration 1 collected 2 units of water.
City configuration 2 collected 14 units of water.
City configuration 3 collected 35 units of water.
City configuration 4 collected 0 units of water.
City configuration 5 collected 0 units of water.
City configuration 6 collected 0 units of water.
City configuration 7 collected 0 units of water.</pre>
 
=={{header|Go}}==
<syntaxhighlight lang="go">
<lang go>
package main
 
Line 1,578 ⟶ 2,522:
fmt.Println(waterCollected([]int{8, 7, 7, 6}))
fmt.Println(waterCollected([]int{6, 7, 10, 7, 6}))
}</langsyntaxhighlight>
 
{{out}}
Line 1,593 ⟶ 2,537:
=={{header|Groovy}}==
 
<syntaxhighlight lang="groovy">
<lang Groovy>
Integer waterBetweenTowers(List<Integer> towers) {
// iterate over the vertical axis. There the amount of water each row can hold is
Line 1,617 ⟶ 2,561:
println "$it => total water: ${waterBetweenTowers it}"
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,634 ⟶ 2,578:
Following the approach of slightly modified [http://stackoverflow.com/users/1416525/cdk cdk]'s Haskell solution at [http://stackoverflow.com/questions/24414700/amazon-water-collected-between-towers/ Stack Overflow]. As recommended in [http://h2.jaguarpaw.co.uk/posts/data-structures-matter/ Programming as if the Correct Data Structure (and Performance) Mattered] it uses [http://hackage.haskell.org/package/vector-0.12.0.1/docs/Data-Vector-Unboxed.html Vector] instead of Array:
 
<langsyntaxhighlight lang="haskell">import Data.Vector.Unboxed (Vector)
import qualified Data.Vector.Unboxed as V
 
Line 1,657 ⟶ 2,601:
, [8, 7, 7, 6]
, [6, 7, 10, 7, 6]
]</langsyntaxhighlight>
{{Out}}
<pre>2
Line 1,670 ⟶ 2,614:
Or, using Data.List for simplicity - no need to prioritize performance here - and adding diagrams:
 
<langsyntaxhighlight lang="haskell">import Data.List (replicate, transpose)
 
-------------- WATER COLLECTED BETWEEN TOWERS ------------
Line 1,718 ⟶ 2,662:
showLegend =
((<>) . show . fmap fst)
<*> ((" -> " <>) . show . foldr ((+) . snd) 0)</langsyntaxhighlight>
{{Out}}
<pre>
Line 1,801 ⟶ 2,745:
 
'''Solution:'''
<langsyntaxhighlight lang="j">collectLevels =: >./\ <. >./\. NB. collect levels after filling
waterLevels=: collectLevels - ] NB. water levels for each tower
collectedWater=: +/@waterLevels NB. sum the units of water collected
printTowers =: ' ' , [: |.@|: '#~' #~ ] ,. waterLevels NB. print a nice graph of towers and water</langsyntaxhighlight>
 
'''Examples:'''
<langsyntaxhighlight lang="j"> collectedWater 5 3 7 2 6 4 5 9 1 2
14
printTowers 5 3 7 2 6 4 5 9 1 2
Line 1,833 ⟶ 2,777:
TestResults =: 2 14 35 0 0 0 0
TestResults -: collectedWater &> TestTowers NB. check tests
1</langsyntaxhighlight>
 
=={{header|Java}}==
{{trans|D}}
<langsyntaxhighlight Javalang="java">public class WaterBetweenTowers {
public static void main(String[] args) {
int i = 1;
Line 1,886 ⟶ 2,830:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>Block 1 holds 2 water units.
Line 1,900 ⟶ 2,844:
===ES5===
{{Trans|Haskell}}
<langsyntaxhighlight JavaScriptlang="javascript">(function () {
'use strict';
 
Line 1,991 ⟶ 2,935:
 
//--> [2, 14, 35, 0, 0, 0, 0]
})();</langsyntaxhighlight>
 
{{Out}}
<langsyntaxhighlight JavaScriptlang="javascript">[2, 14, 35, 0, 0, 0, 0]</langsyntaxhighlight>
 
===ES6===
{{Trans|Haskell}}
<langsyntaxhighlight JavaScriptlang="javascript">(() => {
"use strict";
 
Line 2,131 ⟶ 3,075:
// MAIN ---
return main();
})();</langsyntaxhighlight>
{{Out}}
<langsyntaxhighlight JavaScriptlang="javascript">[2, 14, 35, 0, 0, 0, 0]</langsyntaxhighlight>
 
=={{header|jq}}==
Line 2,140 ⟶ 3,084:
'''Works with gojq, the Go implementation of jq'''
 
<langsyntaxhighlight lang="jq">def waterCollected:
. as $tower
| ($tower|length) as $n
Line 2,159 ⟶ 3,103:
 
towers[]
| "\(waterCollected) from \(.)"</langsyntaxhighlight>
{{out}}
As for [[#Kotlin]] and others.
Line 2,165 ⟶ 3,109:
Inspired to [[#Python]].
 
<langsyntaxhighlight lang="julia">using Printf
 
function watercollected(towers::Vector{Int})
Line 2,208 ⟶ 3,152:
towerprint(towers, watercollected(towers))
println()
end</langsyntaxhighlight>
 
{{out}}
Line 2,290 ⟶ 3,234:
=={{header|Kotlin}}==
{{trans|Python}}
<langsyntaxhighlight lang="scala">// version 1.1.2
 
fun waterCollected(tower: IntArray): Int {
Line 2,312 ⟶ 3,256:
println("${"%2d".format(waterCollected(tower))} from ${tower.contentToString()}")
}
}</langsyntaxhighlight>
 
{{out}}
Line 2,327 ⟶ 3,271:
=={{header|Lua}}==
{{trans|C#}}
<langsyntaxhighlight lang="lua">function waterCollected(i,tower)
local length = 0
for _ in pairs(tower) do
Line 2,384 ⟶ 3,328:
end
 
main()</langsyntaxhighlight>
{{out}}
<pre>Block 1 holds 2 water units.
Line 2,396 ⟶ 3,340:
=={{header|M2000 Interpreter}}==
===Scan min-max for each bar===
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Water {
Flush ' empty stack
Line 2,428 ⟶ 3,372:
}
Water
</syntaxhighlight>
</lang>
===Drain method===
Module Water2 {
Line 2,464 ⟶ 3,408:
}
Water2
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
</syntaxhighlight>
</lang>
===Faster Method===
{{trans|AWK}}
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Water3 {
Flush ' empty stack
Line 2,496 ⟶ 3,440:
}
Water3
</syntaxhighlight>
</lang>
 
{{out}}
Line 2,504 ⟶ 3,448:
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">ClearAll[waterbetween]
waterbetween[h_List] := Module[{mi, ma, ch},
{mi, ma} = MinMax[h];
Line 2,521 ⟶ 3,465:
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}};
waterbetween /@ h</langsyntaxhighlight>
{{out}}
<pre>{2, 14, 35, 0, 0, 0, 0}</pre>
 
=={{header|Nim}}==
<langsyntaxhighlight Nimlang="nim">import math, sequtils, sugar
 
proc water(barChart: seq[int], isLeftPeak = false, isRightPeak = false): int =
Line 2,550 ⟶ 3,494:
const waterUnits = barCharts.map(chart=>water(chart, false, false))
echo(waterUnits)
</syntaxhighlight>
</lang>
{{out}}
<pre>
@[2, 14, 35, 0, 0, 0, 0]
</pre >
 
=={{header|Pascal}}==
{{works with|Delphi|7}}
{{works with|Free Pascal}}
<syntaxhighlight lang="pascal">
program RainInFlatland;
 
{$IFDEF FPC} // Free Pascal
{$MODE Delphi}
{$ELSE} // Delphi
{$APPTYPE CONSOLE}
{$ENDIF}
 
uses SysUtils;
type THeight = integer;
// Heights could be f.p., but some changes to the code would be needed:
// (1) the inc function isn't available for f.p. values,
// (2) the print-out would need extra formatting.
 
{------------------------------------------------------------------------------
Find highest tower; if there are 2 or more equal highest, choose any.
Then fill troughs so that on going towards the highest tower, from the
left-hand or right-hand end, there are no steps down.
Amount of filling required equals amount of water collected.
}
function FillTroughs( const h : array of THeight) : THeight;
var
m, i, i_max : integer;
h_max : THeight;
begin
result := 0;
m := High( h); // highest index, 0-based; there are m + 1 towers
if (m <= 1) then exit; // result = 0 if <= 2 towers
 
// Find highest tower and its index in the array.
h_max := h[0];
i_max := 0;
for i := 1 to m do begin
if h[i] > h_max then begin
h_max := h[i];
i_max := i;
end;
end;
// Fill troughs from left-hand end to highest tower
h_max := h[0];
for i := 1 to i_max - 1 do begin
if h[i] < h_max then inc( result, h_max - h[i])
else h_max := h[i];
end;
// Fill troughs from right-hand end to highest tower
h_max := h[m];
for i := m - 1 downto i_max + 1 do begin
if h[i] < h_max then inc( result, h_max - h[i])
else h_max := h[i];
end;
end;
 
{-------------------------------------------------------------------------
Wrapper for the above: finds amount of water, and prints input and result.
}
procedure CalcAndPrint( h : array of THeight);
var
water : THeight;
j : integer;
begin
water := FillTroughs( h);
Write( water:5, ' <-- [');
for j := 0 to High( h) do begin
Write( h[j]);
if j < High(h) then Write(', ') else WriteLn(']');
end;
end;
 
{---------------------------------------------------------------------------
Main routine.
}
begin
CalcAndPrint([1,5,3,7,2]);
CalcAndPrint([5,3,7,2,6,4,5,9,1,2]);
CalcAndPrint([2,6,3,5,2,8,1,4,2,2,5,3,5,7,4,1]);
CalcAndPrint([5,5,5,5]);
CalcAndPrint([5,6,7,8]);
CalcAndPrint([8,7,7,6]);
CalcAndPrint([6,7,10,7,6]);
end.
</syntaxhighlight>
{{out}}
<pre>
2 <-- [1, 5, 3, 7, 2]
14 <-- [5, 3, 7, 2, 6, 4, 5, 9, 1, 2]
35 <-- [2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1]
0 <-- [5, 5, 5, 5]
0 <-- [5, 6, 7, 8]
0 <-- [8, 7, 7, 6]
0 <-- [6, 7, 10, 7, 6]
</pre>
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">use Modern::Perl;
use List::Util qw{ min max sum };
 
Line 2,579 ⟶ 3,619:
[ 8, 7, 7, 6 ],
[ 6, 7, 10, 7, 6 ],
);</langsyntaxhighlight>
{{Out}}
<pre>2 14 35 0 0 0 0</pre>
Line 2,585 ⟶ 3,625:
=={{header|Phix}}==
=== inefficient one-pass method ===
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function collect_water(sequence heights)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
integer res = 0
<span style="color: #008080;">function</span> <span style="color: #000000;">collect_water</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">heights</span><span style="color: #0000FF;">)</span>
for i=2 to length(heights)-1 do
<span style="color: #004080;">integer</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
integer lm = max(heights[1..i-1]),
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">heights</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
rm = max(heights[i+1..$]),
<span style="color: #004080;">integer</span> <span style="color: #000000;">lm</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">heights</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]),</span>
d = min(lm,rm)-heights[i]
<span style="color: #000000;">rm</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">heights</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$]),</span>
res += max(0,d)
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lm</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rm</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">heights</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
end for
<span style="color: #000000;">res</span> <span style="color: #0000FF;">+=</span> <span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)</span>
return res
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
constant tests = {{1,5,3,7,2},
{5,3,7,2,6,4,5,9,1,2},
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},</span>
{2,6,3,5,2,8,1,4,2,2,5,3,5,7,4,1},
<span style="color: #0000FF;">{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},</span>
{5,5,5,5},
<span style="color: #0000FF;">{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},</span>
{5,6,7,8},
<span style="color: #0000FF;">{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">},</span>
{8,7,7,6},
<span style="color: #0000FF;">{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">},</span>
{6,7,10,7,6}}
<span style="color: #0000FF;">{</span><span style="color: #000000;">8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">6</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">}}</span>
for i=1 to length(tests) do
sequence ti = tests[i]
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
printf(1,"%35s : %d\n",{sprint(ti),collect_water(ti)})
<span style="color: #004080;">sequence</span> <span style="color: #000000;">ti</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
end for</lang>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%35s : %d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">sprint</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">),</span><span style="color: #000000;">collect_water</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 2,619 ⟶ 3,662:
</pre>
=== more efficient two-pass version ===
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function collect_water(sequence heights)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
 
<span style="color: #008080;">function</span> <span style="color: #000000;">collect_water</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">heights</span><span style="color: #0000FF;">)</span>
integer left_max = heights[1],
right_max = heights[$]
<span style="color: #004080;">integer</span> <span style="color: #000000;">left_max</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">heights</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span>
sequence left_height = heights,
<span style="color: #000000;">right_max</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">heights</span><span style="color: #0000FF;">[$]</span>
right_height = heights
<span style="color: #004080;">sequence</span> <span style="color: #000000;">left_height</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">heights</span><span style="color: #0000FF;">),</span>
 
<span style="color: #000000;">right_height</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">heights</span><span style="color: #0000FF;">)</span>
for i=2 to length(heights)-1 do
left_max = max(heights[i],left_max)
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">heights</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
left_height[i] = left_max
<span style="color: #000000;">left_max</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">heights</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">left_max</span><span style="color: #0000FF;">)</span>
right_max = max(heights[-i],right_max)
<span style="color: #000000;">left_height</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">left_max</span>
right_height[-i] = right_max
<span style="color: #000000;">right_max</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">heights</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">right_max</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #000000;">right_height</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">right_max</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
sequence mins = sq_min(left_height,right_height),
diffs = sq_sub(mins,heights)
<span style="color: #004080;">sequence</span> <span style="color: #000000;">mins</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sq_min</span><span style="color: #0000FF;">(</span><span style="color: #000000;">left_height</span><span style="color: #0000FF;">,</span><span style="color: #000000;">right_height</span><span style="color: #0000FF;">),</span>
 
<span style="color: #000000;">diffs</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sq_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mins</span><span style="color: #0000FF;">,</span><span style="color: #000000;">heights</span><span style="color: #0000FF;">)</span>
return sum(diffs)
end function</lang>
<span style="color: #008080;">return</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #000000;">diffs</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<!--</syntaxhighlight>-->
(same output)
 
=== pretty print routine ===
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>procedure print_water(sequence heights)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
integer res = 0, l = length(heights)
<span style="color: #7060A8;">requires</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1.0.2"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (bugfix in p2js.js/$sidii(), 20/4/22)</span>
sequence towers = repeat(repeat(' ',l),max(heights))
<span style="color: #008080;">procedure</span> <span style="color: #000000;">print_water</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">heights</span><span style="color: #0000FF;">)</span>
for i=1 to l do
<span style="color: #004080;">integer</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">heights</span><span style="color: #0000FF;">)</span>
for j=1 to heights[i] do
<span style="color: #004080;">sequence</span> <span style="color: #000000;">towers</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">heights</span><span style="color: #0000FF;">))</span>
towers[-j][i] = '#'
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">l</span> <span style="color: #008080;">do</span>
end for
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">heights</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">do</span>
if i>1 and i<l then
<span style="color: #000000;">towers</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">'#'</span>
integer lm = max(heights[1..i-1]),
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
rm = max(heights[i+1..$]),
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">></span><span style="color: #000000;">1</span> <span style="color: #008080;">and</span> <span style="color: #000000;">i</span><span style="color: #0000FF;"><</span><span style="color: #000000;">l</span> <span style="color: #008080;">then</span>
m = min(lm,rm)
<span style="color: #004080;">integer</span> <span style="color: #000000;">lm</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">heights</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]),</span>
for j=heights[i]+1 to m do
<span style="color: #000000;">rm</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">heights</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$]),</span>
towers[-j][i] = '~'
<span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lm</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rm</span><span style="color: #0000FF;">)</span>
res += 1
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">heights</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">m</span> <span style="color: #008080;">do</span>
end for
<span style="color: #000000;">towers</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">'~'</span>
end if
<span style="color: #000000;">res</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
printf(1,"%s\ncollected:%d\n",{join(towers,"\n"),res})
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end procedure
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
 
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s\ncollected:%d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">towers</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">),</span><span style="color: #000000;">res</span><span style="color: #0000FF;">})</span>
print_water({5,3,7,2,6,4,5,9,1,2})</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">print_water</span><span style="color: #0000FF;">({</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 2,678 ⟶ 3,728:
=={{header|Phixmonti}}==
{{trans|Phix}}
<langsyntaxhighlight Phixmontilang="phixmonti">include ..\Utilitys.pmt
 
def collect_water
Line 2,704 ⟶ 3,754:
len for
get dup print " : " print collect_water ?
endfor</langsyntaxhighlight>
{{out}}
<pre>[1, 5, 3, 7, 2] : 2
Line 2,715 ⟶ 3,765:
 
=== Press any key to exit ===</pre>
 
=={{header|PHP}}==
<syntaxhighlight lang="php"><?php
$tower = "\u{2588}" . "\u{2588}";
$empty = ' ';
$water = '==';
 
$build = array(
array(1, 5, 3, 7, 2),
array(5, 3, 7, 2, 6, 4, 5, 9, 1, 2),
array(2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1),
array(5, 5, 5, 5),
array(5, 6, 7, 8),
array(8, 7, 7, 6),
array(6, 7, 10, 7, 6)
);
 
// Calculate
for ($i = 0; $i < count($build); $i++) {
$level = array();
for ($j = 1; $j < count($build[$i]) - 1; $j++) {
$w = 0;
$l = $r = 0;
for ($k = 0; $k < $j; $k++) {
if ($build[$i][$k] > $build[$i][$j]) {
$l = max($l, $build[$i][$k]);
}
}
for ($k = $j + 1; $k < count($build[$i]); $k++) {
if ($build[$i][$k] > $build[$i][$j]) {
$r = max($r, $build[$i][$k]);
}
}
if ($l > 0 && $r > 0) {
$w = min($l, $r) - $build[$i][$j];
$level[$j] = $w;
}
}
 
// Report
echo '<pre>';
$max = max($build[$i]);
$u = 0;
for ($j = $max; $j > 0; $j--) {
for ($k = 0; $k < count($build[$i]); $k++) {
if ($j - 1 < $build[$i][$k]) {
echo $tower;
}
elseif (!empty($level[$k]) && $level[$k] + $build[$i][$k] >= $j) {
echo $water;
$u++;
}
elseif ($build[$i][$k] < $j) {
echo $empty;
}
}
echo '<br>';
}
echo '<br>Block ' . $i + 1 . ' will collect ' . $u . ' units of water<br>';
echo '</pre>';
}
?></syntaxhighlight>
{{out}}
<pre>
██
██
██==██
██==██
██████
████████
██████████
 
Block 1 will collect 2 units of water
██
██
██========██
██==██====██
██==██==██==████
██==██==████████
██████==████████
████████████████==██
████████████████████
 
Block 2 will collect 14 units of water
██
██==============██
██======██==============██
██==██==██========██==████
██==██==██==██====██==██████
██████==██==██====██████████
████████████==████████████████
████████████████████████████████
 
Block 3 will collect 35 units of water
████████
████████
████████
████████
████████
 
Block 4 will collect 0 units of water
██
████
██████
████████
████████
████████
████████
████████
 
Block 5 will collect 0 units of water
██
██████
████████
████████
████████
████████
████████
████████
 
Block 6 will collect 0 units of water
██
██
██
██████
██████████
██████████
██████████
██████████
██████████
██████████
 
Block 7 will collect 0 units of water</pre>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de water (Lst)
(sum
'((A)
Line 2,734 ⟶ 3,917:
(5 6 7 8)
(8 7 7 6)
(6 7 10 7 6) ) ) )</langsyntaxhighlight>
{{out}}
<pre>(2 14 35 0 0 0 0)</pre>
Line 2,741 ⟶ 3,924:
Based on the algorithm explained at [http://stackoverflow.com/questions/24414700/amazon-water-collected-between-towers/32135773#32135773 Stack Overflow]:
 
<langsyntaxhighlight lang="python">def water_collected(tower):
N = len(tower)
highest_left = [0] + [max(tower[:n]) for n in range(1,N)]
Line 2,763 ⟶ 3,946:
[6, 7, 10, 7, 6]]
 
[water_collected(tower) for tower in towers]</langsyntaxhighlight>
{{Out}}
<pre>
Line 2,813 ⟶ 3,996:
Or, expressed in terms of '''itertools.accumulate''', and showing diagrams:
 
<langsyntaxhighlight lang="python">'''Water collected between towers'''
 
from itertools import accumulate
Line 2,930 ⟶ 4,113:
if __name__ == '__main__':
main()
</syntaxhighlight>
</lang>
{{Out}}
<pre> █
Line 3,038 ⟶ 4,221:
 
[6,7,10,7,6] -> 0</pre>
 
=={{header|Quackery}}==
 
<syntaxhighlight lang="Quackery"> [ $ "turtleduck.qky" loadfile ] now!
 
[ dup 0 = iff drop done
dup 2 times
[ 20 * 1 walk
1 4 turn
20 1 walk
1 4 turn ] ] is bar ( [ --> )
 
[ tuck size unrot
-1 4 turn
witheach
[ dup
' [ 158 151 147 ]
dup colour
fill bar
dup 20 * 1 fly
dip
[ behead
' [ 162 197 208 ]
dup colour
fill bar ]
-20 * 1 fly
1 4 turn
20 1 fly
-1 4 turn ]
drop
1 4 turn
-20 * 1 fly ] is chart ( [ [ --> )
 
[ [] 0 rot witheach
[ max dup dip join ]
drop ] is rightmax ( [ --> [ )
 
[ reverse
rightmax
reverse ] is leftmax ( [ --> [ )
 
[ [] unrot
witheach
[ over i^ peek
min swap dip join ]
drop ] is mins ( [ --> [ )
 
[ [] unrot
witheach
[ over i^ peek
- swap dip join ]
drop ] is diffs ( [ --> [ )
 
[ 0 swap witheach + ] is sum ( [ --> n )
 
[ dup 2dup rightmax
swap leftmax
mins diffs chart ] is task1 ( [ --> )
 
[ dup dup rightmax
swap leftmax
mins diffs sum ] is task2 ( [ --> )
 
turtle
10 frames
-540 1 fly
 
' [ [ 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 ] ]
dup
witheach
[ dup size swap
task1
1+ 20 * 1 fly ]
witheach
[ task2 echo sp ]
1 frames</syntaxhighlight>
 
{{out}}
 
I see from the discussion page that drawing the towers wasn't part of the task. Here they are anyway.
 
"What is the use of a book," thought Alice, "without pictures or conversations?"
 
[[File:Quackery - Water collected between towers.png|thumb|center]]
 
<pre>2 14 35 0 0 0 0</pre>
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">#lang racket/base
(require racket/match)
 
Line 3,074 ⟶ 4,349:
[6 7 10 7 6]]))
(map water-collected-between-towers towerss))
(list 2 14 35 0 0 0 0)))</langsyntaxhighlight>
 
When run produces no output -- meaning that the tests have run successfully.
Line 3,082 ⟶ 4,357:
{{Trans|Haskell}}
 
<syntaxhighlight lang="raku" perl6line>sub max_l ( @a ) { [\max] @a }
sub max_r ( @a ) { ([\max] @a.reverse).reverse }
 
Line 3,101 ⟶ 4,376:
[ 8, 7, 7, 6 ],
[ 6, 7, 10, 7, 6 ],
;</langsyntaxhighlight>
{{Out}}
<pre>(2 14 35 0 0 0 0)</pre>
Line 3,107 ⟶ 4,382:
=={{header|REXX}}==
===version 1===
<langsyntaxhighlight lang="rexx">/* REXX */
Call bars '1 5 3 7 2'
Call bars '5 3 7 2 6 4 5 9 1 2'
Line 3,172 ⟶ 4,447:
Say ol
End
Return</langsyntaxhighlight>
{{out}}
<pre>1 5 3 7 2 -> 2
Line 3,238 ⟶ 4,513:
 
===version 2, simple numeric list output===
<langsyntaxhighlight lang="rexx">/*REXX program calculates and displays the amount of rainwater collected between towers.*/
call tower 1 5 3 7 2
call tower 5 3 7 2 6 4 5 9 1 2
Line 3,260 ⟶ 4,535:
end /*f*/
say right(w.00, 9) 'units of rainwater collected for: ' y /*display water units.*/
return</langsyntaxhighlight>
{{out|output|text=&nbsp;}}
<pre>
Line 3,276 ⟶ 4,551:
 
It tries to protect the aspect ratio by showing the buildings as in this task's preamble.
<langsyntaxhighlight lang="rexx">/*REXX program calculates and displays the amount of rainwater collected between towers.*/
call tower 1 5 3 7 2
call tower 5 3 7 2 6 4 5 9 1 2
Line 3,310 ⟶ 4,585:
do z=t.0 by -1 to 0; say p.z /*display various tower floors & water.*/
end /*z*/
return</langsyntaxhighlight>
{{out|output|text=&nbsp;}}
<pre>
Line 3,374 ⟶ 4,649:
2 ██████████
1 ██████████ no units of rainwater collected
</pre>
 
=={{header|RPL}}==
{{trans|Python}}
{{works with|HP|49/50}}
« DUPDUP SIZE 1 - NDUPN →LIST
DUP 1 « 1 NSUB SUB 0 + « MAX » STREAM » DOSUBS 0 SWAP + <span style="color:grey">@ the seq of max heights to the left of each tower</span>
SWAP 1 « NSUB 1 + OVER SIZE SUB 0 + « MAX » STREAM » DOSUBS 0 + <span style="color:grey">@ the seq of max heights to the right of each tower</span>
MIN SWAP -
1 « 0 MAX » DOLIST ∑LIST
» '<span style="color:blue">WATER</span>' STO
« { {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} }
1 « <span style="color:blue">WATER</span> » DOLIST
» '<span style="color:blue">TASK</span>' STO
{{out}}
<pre>
1: { 2 14 35 0 0 0 0 }
</pre>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">
def a(array)
n=array.length
Line 3,412 ⟶ 4,711:
a([ 8, 7, 7, 6 ])
a([ 6, 7, 10, 7, 6 ])
return</langsyntaxhighlight>
'''output'''
<pre>
Line 3,424 ⟶ 4,723:
 
=={{header|Rust}}==
<langsyntaxhighlight lang="rust">
use std::cmp::min;
 
Line 3,457 ⟶ 4,756:
}
}
</syntaxhighlight>
</lang>
'''output'''
<pre>
Line 3,478 ⟶ 4,777:
{{libheader|Scastie qualified}}
{{works with|Scala|2.13}}
<langsyntaxhighlight Scalalang="scala">import scala.collection.parallel.CollectionConverters.VectorIsParallelizable
 
// Program to find maximum amount of water
Line 3,506 ⟶ 4,805:
println(s"Block ${barSet._2 + 1} could hold max. ${sqBoxWater(barSet._1)} units."))
 
}</langsyntaxhighlight>
 
=={{header|Scheme}}==
<langsyntaxhighlight lang="scheme">(import (scheme base)
(scheme write))
 
Line 3,542 ⟶ 4,841:
(5 6 7 8)
(8 7 7 6)
(6 7 10 7 6)))</langsyntaxhighlight>
{{out}}
<pre>(1 5 3 7 2) -> 2
Line 3,557 ⟶ 4,856:
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">func max_l(Array a, m = a[0]) {
gather { a.each {|e| take(m = max(m, e)) } }
}
Line 3,578 ⟶ 4,877:
[ 8, 7, 7, 6 ],
[ 6, 7, 10, 7, 6 ],
].map { water_collected(_) }.say</langsyntaxhighlight>
{{out}}
<pre>
Line 3,585 ⟶ 4,884:
 
=={{header|Swift}}==
<langsyntaxhighlight lang="swift">// Based on this answer from Stack Overflow:
// https://stackoverflow.com/a/42821623
 
Line 3,618 ⟶ 4,917:
[6, 7, 10, 7, 6]] {
print("water collected = \(waterCollected(heights))")
}</langsyntaxhighlight>
 
{{out}}
Line 3,632 ⟶ 4,931:
 
=={{header|Tailspin}}==
<langsyntaxhighlight lang="tailspin">
templates histogramWater
$ -> \( @: 0"1";
[$... -> ($)"1"-> { leftMax: $ -> #, value: ($)"1" } ] !
when <$@..> do @: $; $ !
otherwise $@ !
Line 3,647 ⟶ 4,946:
\) !
end histogramWater
 
[[1, 5, 3, 7, 2],
[5, 3, 7, 2, 6, 4, 5, 9, 1, 2],
Line 3,655 ⟶ 4,954:
[8, 7, 7, 6],
[6, 7, 10, 7, 6]]... -> '$ -> histogramWater; water in $;$#10;' -> !OUT::write
</syntaxhighlight>
</lang>
 
{{out}}
<pre>
2"1" water in [1, 5, 3, 7, 2]
14"1" water in [5, 3, 7, 2, 6, 4, 5, 9, 1, 2]
35"1" water in [2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1]
0"1" water in [5, 5, 5, 5]
0"1" water in [5, 6, 7, 8]
0"1" water in [8, 7, 7, 6]
0"1" water in [6, 7, 10, 7, 6]
</pre>
 
=={{header|Tcl}}==
Tcl makes for a surprisingly short and readable implementation, next to some of the more functional-oriented languages.
<langsyntaxhighlight Tcllang="tcl">namespace path {::tcl::mathfunc ::tcl::mathop}
 
proc flood {ground} {
Line 3,704 ⟶ 5,003:
} {
puts [flood $p]:\t$p
}</langsyntaxhighlight>
 
{{out}}
Line 3,716 ⟶ 5,015:
0: 6 7 10 7 6</pre>
 
=={{header|Visual Basic .NETUiua}}==
{{works with|Uiua|0.11.1}}
===Version 1===
<syntaxhighlight lang="uiua">
'''Method:''' Instead of "scanning" adjoining towers for each column, this routine converts the tower data into a string representation with building blocks, empty spaces, and potential water retention sites. The potential water retention sites are then "eroded" away where they are found to be unsupported. This is accomplished with the '''.Replace()''' function. The replace operations are unleashed upon the entire "block" of towers, rather than a cell at a time or a line at a time - which perhaps increases the program's execution-time, but reduces program's complexity.
Area ← /+-:↧⍜⇌\↥⟜\↥.
 
{[1 5 3 7 2]
The program can optionally display the interim string representation of each tower block before the final count is completed. I've since modified it to have the same block and wavy characters are the
[5 3 7 2 6 4 5 9 1 2]
[[{{FULLPAGENAME}}#version_3|REXX 9.3]] output, but used the double-wide columns, as pictured in the task definition area.
[2 6 3 5 2 8 1 4 2 2 5 3 5 7 4 1]
<lang vbnet>' Convert tower block data into a string representation, then manipulate that.
[5 5 5 5]
Module Module1
[5 6 7 8]
Sub Main(Args() As String)
[8 7 7 6]
Dim shoTow As Boolean = Environment.GetCommandLineArgs().Count > 1 ' Show towers.
[6 7 10 7 6]}
Dim wta As Integer()() = { ' Water tower array (input data).
∵◇Area
New Integer() {1, 5, 3, 7, 2}, New Integer() {5, 3, 7, 2, 6, 4, 5, 9, 1, 2},
</syntaxhighlight>
New Integer() {2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1},
{{out}}
New Integer() {5, 5, 5, 5}, New Integer() {5, 6, 7, 8},
<pre>
New Integer() {8, 7, 7, 6}, New Integer() {6, 7, 10, 7, 6}}
[2 14 35 0 0 0 0]
Dim blk As String, ' String representation of a block of towers.
</pre>
lf As String = vbLf, ' Line feed to separate floors in a block of towers.
tb = "██", wr = "≈≈", mt = " " ' Tower Block, Water Retained, eMpTy space.
For i As Integer = 0 To wta.Length - 1
Dim bpf As Integer ' Count of tower blocks found per floor.
blk = ""
Do
bpf = 0 : Dim floor As String = "" ' String representation of each floor.
For j As Integer = 0 To wta(i).Length - 1
If wta(i)(j) > 0 Then ' Tower block detected, add block to floor,
floor &= tb : wta(i)(j) -= 1 : bpf += 1 ' reduce tower by one.
Else ' Empty space detected, fill when not first or last column.
floor &= If(j > 0 AndAlso j < wta(i).Length - 1, wr, mt)
End If
Next
If bpf > 0 Then blk = floor & lf & blk ' Add floors until blocks are gone.
Loop Until bpf = 0 ' No tower blocks left, so terminate.
' Erode potential water retention cells from left and right.
While blk.Contains(mt & wr) : blk = blk.Replace(mt & wr, mt & mt) : End While
While blk.Contains(wr & mt) : blk = blk.Replace(wr & mt, mt & mt) : End While
' Optionaly show towers w/ water marks.
If shoTow Then Console.Write("{0}{1}", lf, blk)
' Subtract the amount of non-water mark characters from the total char amount.
Console.Write("Block {0} retains {1,2} water units.{2}", i + 1,
(blk.Length - blk.Replace(wr, "").Length) \ 2, lf)
Next
End Sub
End Module</lang>
{{out}}<lang>Block 1 retains 2 water units.
Block 2 retains 14 water units.
Block 3 retains 35 water units.
Block 4 retains 0 water units.
Block 5 retains 0 water units.
Block 6 retains 0 water units.
Block 7 retains 0 water units.</lang>
Verbose output shows towers with water ("Almost equal to" characters) left in the "wells" between towers. Just supply any command-line parameter to see it. Use no command line parameters to see the plain output above.
<lang> ██
██
██≈≈██
██≈≈██
██████
████████
██████████
Block 1 retains 2 water units.
 
██
██
██≈≈≈≈≈≈≈≈██
██≈≈██≈≈≈≈██
██≈≈██≈≈██≈≈████
██≈≈██≈≈████████
██████≈≈████████
████████████████≈≈██
████████████████████
Block 2 retains 14 water units.
 
██
██≈≈≈≈≈≈≈≈≈≈≈≈≈≈██
██≈≈≈≈≈≈██≈≈≈≈≈≈≈≈≈≈≈≈≈≈██
██≈≈██≈≈██≈≈≈≈≈≈≈≈██≈≈████
██≈≈██≈≈██≈≈██≈≈≈≈██≈≈██████
██████≈≈██≈≈██≈≈≈≈██████████
████████████≈≈████████████████
████████████████████████████████
Block 3 retains 35 water units.
 
████████
████████
████████
████████
████████
Block 4 retains 0 water units.
 
██
████
██████
████████
████████
████████
████████
████████
Block 5 retains 0 water units.
 
██
██████
████████
████████
████████
████████
████████
████████
Block 6 retains 0 water units.
 
██
██
██
██████
██████████
██████████
██████████
██████████
██████████
██████████
Block 7 retains 0 water units.</lang>
===Version 2===
'''Method:''' More conventional "scanning" method. A Char array is used, but no Replace() statements. Output is similar to version 1, although there is now a left margin of three spaces, the results statement is immediately to the right of the string representation of the tower blocks (instead of underneath), the verb is "hold(s)" instead of "retains", and there is a special string when the results indicate zero.
 
<lang vbnet>Module Module1
''' <summary>
''' wide - Widens the aspect ratio of a linefeed separated string.
''' </summary>
''' <param name="src">A string representing a block of towers.</param>
''' <param name="margin">Optional padding for area to the left.</param>
''' <returns>A double-wide version of the string.</returns>
Function wide(src As String, Optional margin As String = "") As String
Dim res As String = margin : For Each ch As Char In src
res += If(ch < " ", ch & margin, ch + ch) : Next : Return res
End Function
 
''' <summary>
''' cntChar - Counts characters, also custom formats the output.
''' </summary>
''' <param name="src">The string to count characters in.</param>
''' <param name="ch">The character to be counted.</param>
''' <param name="verb">Verb to include in format. Expecting "hold",
''' but can work with "retain" or "have".</param>
''' <returns>The count of chars found in a string, and formats a verb.</returns>
Function cntChar(src As String, ch As Char, verb As String) As String
Dim cnt As Integer = 0
For Each c As Char In src : cnt += If(c = ch, 1, 0) : Next
Return If(cnt = 0, "does not " & verb & " any",
verb.Substring(0, If(verb = "have", 2, 4)) & "s " & cnt.ToString())
End Function
 
''' <summary>
''' report - Produces a report of the number of rain units found in
''' a block of towers, optionally showing the towers.
''' Autoincrements the blkID for each report.
''' </summary>
''' <param name="tea">An int array with tower elevations.</param>
''' <param name="blkID">An int of the block of towers ID.</param>
''' <param name="verb">The verb to use in the description.
''' Defaults to "has / have".</param>
''' <param name="showIt">When true, the report includes a string representation
''' of the block of towers.</param>
''' <returns>A string containing the amount of rain units, optionally preceeded by
''' a string representation of the towers holding any water.</returns>
Function report(tea As Integer(), ' Tower elevation array.
ByRef blkID As Integer, ' Block ID for the description.
Optional verb As String = "have", ' Verb to use in the description.
Optional showIt As Boolean = False) As String ' Show representaion.
Dim block As String = "", ' The block of towers.
lf As String = vbLf, ' The separator between floors.
rTwrPos As Integer ' The position of the rightmost tower of this floor.
Do
For rTwrPos = tea.Length - 1 To 0 Step -1 ' Determine the rightmost tower
If tea(rTwrPos) > 0 Then Exit For ' postition on this floor.
Next
If rTwrPos < 0 Then Exit Do ' When no towers remain, exit the do loop.
' init the floor to a space filled Char array, as wide as the block of towers.
Dim floor As Char() = New String(" ", tea.Length).ToCharArray()
Dim bpf As Integer = 0 ' The count of blocks found per floor.
For column As Integer = 0 To rTwrPos ' Scan from left to right.
If tea(column) > 0 Then ' If a tower exists here,
floor(column) = "█" ' mark the floor with a block,
tea(column) -= 1 ' drop the tower elevation by one,
bpf += 1 ' and advance the block count.
ElseIf bpf > 0 Then ' Otherwise, see if a tower is present to the left.
floor(column) = "≈" ' OK to fill with water.
End If
Next
If bpf > If(showIt, 0, 1) Then ' Continue the building only when needed.
' If not showing blocks, discontinue building when a single tower remains.
' build tower blocks string with each floor added to top.
block = New String(floor) & If(block = "", "", lf) & block
Else
Exit Do ' Ran out of towers, so exit the do loop.
End If
Loop While True ' Depending on previous break statements to terminate the do loop.
blkID += 1 ' increment block ID counter.
' format report and return it.
Return If(showIt, String.Format(vbLf & "{0}", wide(block, " ")), "") &
String.Format(" Block {0} {1} water units.", blkID, cntChar(block, "≈", verb))
End Function
 
''' <summary>
''' Main routine.
'''
''' With one command line parameter, it shows tower blocks,
''' with no command line parameters, it shows a plain report
'''</summary>
Sub Main()
Dim shoTow As Boolean = Environment.GetCommandLineArgs().Count > 1 ' Show towers.
Dim blkCntr As Integer = 0 ' Block ID for reports.
Dim verb As String = "hold" ' "retain" or "have" can be used instead of "hold".
Dim tea As Integer()() = {New Integer() {1, 5, 3, 7, 2}, ' Tower elevation data.
New Integer() {5, 3, 7, 2, 6, 4, 5, 9, 1, 2},
New Integer() {2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1},
New Integer() {5, 5, 5, 5}, New Integer() {5, 6, 7, 8},
New Integer() {8, 7, 7, 6}, New Integer() {6, 7, 10, 7, 6}}
For Each block As Integer() In tea
' Produce report for each block of towers.
Console.WriteLine(report(block, blkCntr, verb, shoTow))
Next
End Sub
End Module</lang>
Regular version 2 output:
<lang> Block 1 holds 2 water units.
Block 2 holds 14 water units.
Block 3 holds 35 water units.
Block 4 does not hold any water units.
Block 5 does not hold any water units.
Block 6 does not hold any water units.
Block 7 does not hold any water units.</lang>
Sample of version 2 verbose output:
<lang> ██
██≈≈≈≈≈≈≈≈≈≈≈≈≈≈██
██≈≈≈≈≈≈██≈≈≈≈≈≈≈≈≈≈≈≈≈≈██
██≈≈██≈≈██≈≈≈≈≈≈≈≈██≈≈████
██≈≈██≈≈██≈≈██≈≈≈≈██≈≈██████
██████≈≈██≈≈██≈≈≈≈██████████
████████████≈≈████████████████
████████████████████████████████ Block 3 holds 35 water units.
 
████████
████████
████████
████████
████████ Block 4 does not hold any water units.</lang>
 
=={{header|Wren}}==
Line 3,965 ⟶ 5,039:
{{libheader|Wren-math}}
{{libheader|Wren-fmt}}
<langsyntaxhighlight ecmascriptlang="wren">import "./math" for Math, Nums
import "./fmt" for Fmt
 
var waterCollected = Fn.new { |tower|
Line 3,985 ⟶ 5,059:
[6, 7, 10, 7, 6]
]
for (tower in towers) Fmt.print("$2d from $n", waterCollected.call(tower), tower)</langsyntaxhighlight>
 
{{out}}
Line 3,999 ⟶ 5,073:
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">func WaterCollected(Array, Width); \Return amount of water collected
int Array, Width, Height, I, Row, Col, Left, Right, Water;
[Water:= 0; Height:= 0;
Line 4,031 ⟶ 5,105:
ChOut(0, ^ );
];
]</langsyntaxhighlight>
 
{{out}}
Line 4,037 ⟶ 5,111:
2 14 35 0 0 0 0
</pre>
 
=={{header|Yabasic}}==
{{trans|AWK}}
<lang Yabasic>data 7
data "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"
data "5,5,5,5", "5,6,7,8", "8,7,7,6", "6,7,10,7,6"
 
read n
 
for i = 1 to n
read n$
wcbt(n$)
next i
 
sub wcbt(s$)
local tower$(1), hr(1), hl(1), n, i, ans, k
n = token(s$, tower$(), ",")
 
redim hr(n)
redim hl(n)
for i = n to 1 step -1
if i < n then
k = hr(i + 1)
else
k = 0
end if
hr(i) = max(val(tower$(i)), k)
next i
for i = 1 to n
if i then
k = hl(i - 1)
else
k = 0
end if
hl(i) = max(val(tower$(i)), k)
ans = ans + min(hl(i), hr(i)) - val(tower$(i))
next i
print ans," ",n$
end sub</lang>
 
=={{header|zkl}}==
{{trans|Haskell}}
<langsyntaxhighlight lang="zkl">fcn waterCollected(walls){
// compile max wall heights from left to right and right to left
// then each pair is left/right wall of that cell.
Line 4,093 ⟶ 5,127:
xs.reduce('wrap(s,x,a){ s=f(s,x); a.append(s); s },i,ss:=List());
ss
} // scanl((1,5,3,7,2),max,0) --> (1,5,5,7,7)</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">T( T(1, 5, 3, 7, 2), T(5, 3, 7, 2, 6, 4, 5, 9, 1, 2),
T(2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1),
T(5, 5, 5, 5), T(5, 6, 7, 8),T(8, 7, 7, 6),
T(6, 7, 10, 7, 6) )
.pump(List, waterCollected).println();</langsyntaxhighlight>
{{out}}
<pre>