----------------------------------------------------------------------
-- Aufgabe: summiere 1..n.
-- Methode: tasks fuer Teilsummen 1..n/2, n/2+1..n
--          erste task startet die zweite und bildet Gesamtergebnis
----------------------------------------------------------------------

with Stringpack; use Stringpack;
procedure Arbeitsteilung2 is

   task Worker is
      entry Start(From, To: Integer);
      entry Result(Res: out Integer);
   end Worker;

   task Helper is
      entry Start(From, To: Integer);
      entry Result(Res: out Integer);
   end Helper;

   task body Worker is
      Local_From, Local_To, Local_Res, Remote_Res: Integer;
   begin
      accept Start(From, To: Integer) do
         Local_From := From;
         Local_To := To;
      end Start;
      Helper.Start(Local_From, (Local_From + Local_To)/2);
      Local_Res := 0;
      for I in ((Local_From + Local_To)/2 +1)..Local_To loop
         Local_Res := Local_Res+I;
      end loop;
      Helper.Result(Remote_Res);
      accept Result(Res: out Integer) do
         Res := Local_Res + Remote_Res;
      end Result;
   end Worker;

   task body Helper is
      Local_From, Local_To, Local_Res: Integer;
   begin
      accept Start(From, To: Integer) do
         Local_From := From;
         Local_To := To;
      end Start;
      Local_Res := 0;
      for I in Local_From..Local_To loop
         Local_Res := Local_Res+I;
      end loop;
      accept Result(Res: out Integer) do
         Res := Local_Res;
      end Result;
   end Helper;

   N, Sum: Integer;

begin
   Print("give natural");
   N := Getint;
   Worker.Start(1, N);
   Worker.Result(Sum);
   Print("Summe= " & Sum);
end Arbeitsteilung2;

