Module Module1 ''' ''' wide - Widens the aspect ratio of a linefeed separated string. ''' ''' A string representing a block of towers. ''' Optional padding for area to the left. ''' A double-wide version of the string. 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 ''' ''' cntChar - Counts characters, also custom formats the output. ''' ''' The string to count characters in. ''' The character to be counted. ''' Verb to include in format. Expecting "hold", ''' but can work with "retain" or "have". ''' The count of chars found in a string, and formats a verb. 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 ''' ''' 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. ''' ''' An int array with tower elevations. ''' An int of the block of towers ID. ''' The verb to use in the description. ''' Defaults to "has / have". ''' When true, the report includes a string representation ''' of the block of towers. ''' A string containing the amount of rain units, optionally preceeded by ''' a string representation of the towers holding any water. 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 ''' ''' Main routine. ''' ''' With one command line parameter, it shows tower blocks, ''' with no command line parameters, it shows a plain report ''' 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