Task: Water collected between towers





Java: public class WaterBetweenTowers {
    public static void main(String[] args) {
        int i = 1;
        int[][] tba = new int[][]{
            new int[]{1, 5, 3, 7, 2},
            new int[]{5, 3, 7, 2, 6, 4, 5, 9, 1, 2},
            new int[]{2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1},
            new int[]{5, 5, 5, 5},
            new int[]{5, 6, 7, 8},
            new int[]{8, 7, 7, 6},
            new int[]{6, 7, 10, 7, 6}
        };

        for (int[] tea : tba) {
            int rht, wu = 0, bof;
            do {
                for (rht = tea.length - 1; rht >= 0; rht--) {
                    if (tea[rht] > 0) {
                        break;
                    }
                }

                if (rht < 0) {
                    break;
                }

                bof = 0;
                for (int col = 0; col <= rht; col++) {
                    if (tea[col] > 0) {
                        tea[col]--;
                        bof += 1;
                    } else if (bof > 0) {
                        wu++;
                    }
                }
                if (bof < 2) {
                    break;
                }
            } while (true);

            System.out.printf("Block %d", i++);
            if (wu == 0) {
                System.out.print(" does not hold any");
            } else {
                System.out.printf(" holds %d", wu);
            }
            System.out.println(" water units.");
        }
    }
}







Ada: with Ada.Text_IO;

procedure Water_Collected is

   type Bar_Index     is new Positive;
   type Natural_Array is array (Bar_Index range <>) of Natural;

   subtype Bar_Array   is Natural_Array;
   subtype Water_Array is Natural_Array;

   function Flood (Bars : Bar_Array; Forward : Boolean) return Water_Array is
      R : Water_Array (Bars'Range);
      H : Natural := 0;
   begin
      if Forward then
         for A in R'Range loop
            H     := Natural'Max (H, Bars (A));
            R (A) := H - Bars (A);
         end loop;
      else
         for A in reverse R'Range loop
            H     := Natural'Max (H, Bars (A));
            R (A) := H - Bars (A);
         end loop;
      end if;
      return R;
   end Flood;

   function Fold (Left, Right : Water_Array) return Water_Array is
      R : Water_Array (Left'Range);
   begin
      for A in R'Range loop
         R (A) := Natural'Min (Left (A), Right (A));
      end loop;
      return R;
   end Fold;

   function Fill (Bars : Bar_Array) return Water_Array
   is (Fold (Flood (Bars, Forward => True),
             Flood (Bars, Forward => False)));

   function Sum_Of (Bars : Natural_Array) return Natural is
      Sum : Natural := 0;
   begin
      for Bar of Bars loop
         Sum := Sum + Bar;
      end loop;
      return Sum;
   end Sum_Of;

   procedure Show (Bars : Bar_Array) is
      use Ada.Text_IO;
      Water : constant Water_Array := Fill (Bars);
   begin
      Put ("The series: [");
      for Bar of Bars loop
         Put (Bar'Image);
         Put (" ");
      end loop;
      Put ("] holds ");
      Put (Sum_Of (Water)'Image);
      Put (" units of water.");
      New_Line;
   end Show;

begin
   Show ((1, 5, 3, 7, 2));
   Show ((5, 3, 7, 2, 6, 4, 5, 9, 1, 2));
   Show ((2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1));
   Show ((5, 5, 5, 5));
   Show ((5, 6, 7, 8));
   Show ((8, 7, 7, 6));
   Show ((6, 7, 10, 7, 6));
end Water_Collected;