package Sieve is
type Primes is array ( Natural range <> ) of Boolean;
procedure Make_Sieve ( Sieve : in out Primes );
procedure Work_Sieve ( Sieve : in out Primes );
procedure Find_Bounds ( Sieve : in Primes; Low : in out Integer; High : in out Integer );
procedure Show_Twins ( Sieve : in Primes; Low : in Integer; High : in Integer );
end Sieve;
with Ada.Text_IO;
with Ada.Integer_Text_IO;
with Ada.Numerics.Elementary_Functions;
package body Sieve is
procedure Make_Sieve ( Sieve : in out Primes ) is
begin
Sieve := ( 0 | 1 => false, others => true );
end Make_Sieve;
procedure Work_Sieve ( Sieve : in out Primes ) is
use Ada.Numerics.Elementary_Functions;
Highest_Factor : Integer := Integer ( Sqrt ( Float ( Sieve'Last ) ) );
begin
for Iterator_1 in 2 .. Highest_Factor loop
if Sieve ( Iterator_1 ) = true then
for Iterator_2 in Iterator_1 + 1 .. Sieve'Last loop
if Iterator_2 mod Iterator_1 = 0 then
Sieve ( Iterator_2 ) := false;
end if;
end loop;
end if;
end loop;
end Work_Sieve;
procedure Find_Bounds ( Sieve : in Primes; Low : in out Integer; High : in out Integer ) is
use Ada.Text_IO;
use Ada.Integer_Text_IO;
begin
loop
loop
Put ( "Upper Bound : " );
Get ( High );
exit when High /= 0 and High /= Sieve'Last;
end loop;
loop
Put ( "Lower Bound : " );
Get ( Low );
exit when Low /= 0 and Low /= Sieve'Last;
end loop;
exit when Low < High;
Put_Line ( "Upper Bound !> Lower Bound" );
end loop;
end Find_Bounds;
procedure Show_Twins ( Sieve : in Primes; Low : in Integer; High : in Integer ) is
use Ada.Text_IO;
use Ada.Integer_Text_IO;
Count : Integer := 0;
begin
for Iterator in Low .. High loop
if Sieve ( Iterator ) = true and Sieve ( Iterator + 2 ) = true then
Count := Count + 1;
Put ( Iterator, 6 ); Put ( " and " ); Put ( Iterator + 2, 6 ); New_Line;
end if;
end loop;
Put_Line ( Integer'Image ( Count ) & " twin pairs in range" & Integer'Image ( Low ) & " .." & Integer'Image ( High ) & "." );
end Show_Twins;
end Sieve;
with Sieve;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure Main is
use Sieve;
The_Array : Primes ( 0 .. 250_001 );
Low, High : Integer;
begin
Make_Sieve ( The_Array );
Work_Sieve ( The_Array );
Find_Bounds ( The_Array, Low, High );
Show_Twins ( The_Array, Low, High );
end Main;