Task: Water collected between towers




Go: package main

import "fmt"

func maxl(hm []int ) []int{
	res := make([]int,len(hm))
	max := 1
	for i := 0; i < len(hm);i++{
		if(hm[i] > max){
			max = hm[i]
		}
		res[i] = max;
	}
	return res
}
func maxr(hm []int ) []int{
	res := make([]int,len(hm))
	max := 1
	for i := len(hm) - 1 ; i >= 0;i--{
		if(hm[i] > max){
			max = hm[i]
		}
		res[i] = max;
	}
	return res
}
func min(a,b []int)  []int {
	res := make([]int,len(a))
	for i := 0; i < len(a);i++{
		if a[i] >= b[i]{
			res[i] = b[i]
		}else {
			res[i] = a[i]
		}
	}
	return res
}
func diff(hm, min []int) []int {
	res := make([]int,len(hm))
	for i := 0; i < len(hm);i++{
		if min[i] > hm[i]{
			res[i] = min[i] - hm[i]
		}
	}
	return res
}
func sum(a []int) int {
	res := 0
	for i := 0; i < len(a);i++{
		res += a[i]
	}
	return res
}

func waterCollected(hm []int) int {
	maxr := maxr(hm)
	maxl := maxl(hm)
	min := min(maxr,maxl)
	diff := diff(hm,min)
	sum := sum(diff)
	return sum
}


func main() {
	fmt.Println(waterCollected([]int{1, 5, 3, 7, 2}))
	fmt.Println(waterCollected([]int{5, 3, 7, 2, 6, 4, 5, 9, 1, 2}))
	fmt.Println(waterCollected([]int{2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1}))
	fmt.Println(waterCollected([]int{5, 5, 5, 5}))
	fmt.Println(waterCollected([]int{5, 6, 7, 8}))
	fmt.Println(waterCollected([]int{8, 7, 7, 6}))
	fmt.Println(waterCollected([]int{6, 7, 10, 7, 6}))
}








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;