Task: Water collected between towers


C++: #include <iostream>
#include <vector>
#include <algorithm>

enum { EMPTY, WALL, WATER };

auto fill(const std::vector<int> b) {
  auto water = 0;
  const auto rows = *std::max_element(std::begin(b), std::end(b));
  const auto cols = std::size(b);
  std::vector<std::vector<int>> g(rows);
  for (auto& r : g) {
    for (auto i = 0; i < cols; ++i) {
      r.push_back(EMPTY);
    }
  }
  for (auto c = 0; c < cols; ++c) {
    for (auto r = rows - 1u, i = 0u; i < b[c]; ++i, --r) {
      g[r][c] = WALL;
    }
  }
  for (auto c = 0; c < cols - 1; ++c) {
    auto start_row = rows - b[c];
    while (start_row < rows) {
      if (g[start_row][c] == EMPTY) break;
      auto c2 = c + 1;
      bool hitWall = false;
      while (c2 < cols) {
        if (g[start_row][c2] == WALL) {
          hitWall = true;
          break;
        }
        ++c2;
      }
      if (hitWall) {
        for (auto i = c + 1; i < c2; ++i) {
          g[start_row][i] = WATER;
          ++water;
        }
      }
      ++start_row;
    }
  }
  return water;
}

int main() {
  std::vector<std::vector<int>> b = {
    { 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 }
  };
  for (const auto v : b) {
    auto water = fill(v);
    std::cout << water << " water drops." << std::endl;
  }
  std::cin.ignore();
  std::cin.get();
  return 0;
}







VB: 
Module Module1
    Sub Main(Args() As String)
        Dim shoTow As Boolean = Environment.GetCommandLineArgs().Count > 1  
        Dim wta As Integer()() = {                       
            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,                   
            lf As String = vbLf,      
            tb = "██", wr = "≈≈", mt = "  "    
        For i As Integer = 0 To wta.Length - 1
            Dim bpf As Integer                    
            blk = ""
            Do
                bpf = 0 : Dim floor As String = ""  
                For j As Integer = 0 To wta(i).Length - 1
                    If wta(i)(j) > 0 Then      
                        floor &= tb : wta(i)(j) -= 1 : bpf += 1    
                    Else  
                        floor &= If(j > 0 AndAlso j < wta(i).Length - 1, wr, mt)
                    End If
                Next
                If bpf > 0 Then blk = floor & lf & blk 
            Loop Until bpf = 0                       
            
            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
            
            If shoTow Then Console.Write("{0}{1}", lf, blk)
            
            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