Water collected between towers: Difference between revisions

Content added Content deleted
(Added vb.Net program, features erosion of strings method instead of tower height comparison method,)
(→‎{{header|Visual Basic .NET}}: simplified water tower array (wta) declaration, streamlined code to take advantage of preset sub-array lengths.)
Line 1,198: Line 1,198:
Sub Main()
Sub Main()
Dim shoTow As Boolean = Environment.GetCommandLineArgs().Count > 1 ' Show towers.
Dim shoTow As Boolean = Environment.GetCommandLineArgs().Count > 1 ' Show towers.
Dim wta(,) As Integer = {{1, 5, 3, 7, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Dim wta As Integer()() = { ' water tower array (input data).
{5, 3, 7, 2, 6, 4, 5, 9, 1, 2, 0, 0, 0, 0, 0, 0},
New Integer() {1, 5, 3, 7, 2}, New Integer() {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},
New Integer() {2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1},
{5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
New Integer() {5, 5, 5, 5}, New Integer() {5, 6, 7, 8},
{5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
New Integer() {8, 7, 7, 6}, New Integer() {6, 7, 10, 7, 6}}
{8, 7, 7, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{6, 7, 10, 7, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
Dim blk As String, ' String representation of a block of towers.
Dim blk As String, ' String representation of a block of towers.
lf As String = vbCrLf ' Line feed to separate floors in block of towers.
lf As String = vbCrLf ' Line feed to separate floors in a block of towers.
For i As Integer = 0 To UBound(wta, 1)
For i As Integer = 0 To UBound(wta)
Dim ctb As Integer = -1, ' Count of tower blocks found per line.
Dim bpl As Integer ' Count of tower blocks found per line.
lc As Integer, ' Previous count.
lim As Integer = UBound(wta, 2) ' Limit of block length.
blk = ""
blk = ""
Do
Do
lc = ctb : ctb = 0
bpl = 0
For j As Integer = 0 To lim
For j As Integer = 0 To UBound(wta(i))
If wta(i, j) > 0 Then ' Tower block detected, add block to string,
If wta(i)(j) > 0 Then ' Tower block detected, add block to string,
blk &= "B" : wta(i, j) -= 1 : ctb += 1 ' reduce tower by one.
blk &= "B" : wta(i)(j) -= 1 : bpl += 1 ' reduce tower by one.
Else ' Empty space detected, fill if not first or last column.
Else ' Empty space detected, fill if not first or last column.
' Periods are possible water retention cells.
' Periods are possible water retention cells.
blk &= If(j > 0 AndAlso j < lim, ".", " ")
blk &= If(j > 0 AndAlso j < UBound(wta(i)), ".", " ")
End If
End If
Next
Next
If lc < 0 Then ' Set new limit on first floor,
If bpl > 0 Then blk &= lf ' Add floors until no blocks are left.
lim = Math.Max(lc, ctb) - 1 ' and trim initial string.
Loop Until bpl = 0 ' No tower blocks left, so terminate.
blk = Mid(blk, 1, Len(blk) - (UBound(wta, 2) - lim)) & lf
Else
If ctb > 0 Then blk &= lf ' Add floors until no blocks are left.
End If
Loop Until ctb = 0 ' No tower blocks left, so terminate.
' Now erode potential water retention cells from left and right
' Now erode potential water retention cells from left and right
While blk.Contains(" .") : blk = Replace(blk, " .", " ") : End While
While blk.Contains(" .") : blk = Replace(blk, " .", " ") : End While
Line 1,234: Line 1,225:
' Optionally show towers w/ water marks.
' Optionally show towers w/ water marks.
If shoTow Then Console.WriteLine(lf & blk)
If shoTow Then Console.WriteLine(lf & blk)
' Lastly, remove everything except the water marks,
' Now remove all building blocks and whitespace, leaving only water marks.
' then count the remaining characters with Len().
Console.WriteLine("Block {0} retains {1,2} water units.", i + 1,
Console.WriteLine("Block {0} retains {1,2} water units.", i + 1,
Len(Replace(Replace(Replace(blk, lf, ""), "B", ""), " ", "")))
Len(Replace(Replace(Replace(blk, lf, ""), "B", ""), " ", "")))