[Shootout-list] Ada count-words
Marius Amado Alves
amado.alves@netcabo.pt
Thu, 24 Mar 2005 02:20:55 +0000
-- The Great Computer Language Shootout
-- http://shootout.alioth.debian.org/
--
-- contributed by Marius Amado Alves
--
-- gnatmake -O3 count_words.adb
with Ada.Characters.Handling;
with Ada.Characters.Latin_1;
with Ada.Command_Line;
with Ada.Streams;
with Ada.Streams.Stream_IO;
with Ada.Strings.Fixed;
with Ada.Text_IO;
with Ada.Text_IO.Text_Streams;
procedure Count_Words is
use Ada.Characters.Handling;
use Ada.Characters.Latin_1;
use Ada.Command_Line;
use Ada.Streams;
use Ada.Streams.Stream_IO;
use Ada.Text_IO;
use Ada.Text_IO.Text_Streams;
Buffer : Stream_Element_Array (1 .. 4096);
Input_Stream : Ada.Text_IO.Text_Streams.Stream_Access
:= Ada.Text_IO.Text_Streams.Stream (Current_Input);
EOL_Character_Pos : Stream_Element := Character'Pos (LF);
Lines : Natural := 0;
Words : Natural := 0;
Total : Natural := 0;
In_Word : Boolean := False;
N : Stream_Element_Offset;
Is_Separator : array (Stream_Element) of Boolean :=
(0 .. 32 | 127 .. 159 => True, others => False);
procedure Begin_Word is
begin
Words := Words + 1;
In_Word := True;
end;
procedure End_Word is
begin
In_Word := False;
end;
procedure End_Line is
begin
Lines := Lines + 1;
End_Word;
end;
procedure Count_Words (S : in Stream_Element_Array) is
begin
Total := Total + S'Length;
for I in S'Range loop
if S (I) = EOL_Character_Pos then
End_Line;
else
if Is_Separator (S (I)) then
if In_Word then End_Word; end if;
else
if not In_Word then Begin_Word; end if;
end if;
end if;
end loop;
end;
pragma Inline (Begin_Word, End_Word, End_Line, Count_Words);
begin
begin
EOL_Character_Pos := Stream_Element'Value (Argument (1));
exception
when Constraint_Error => null;
end;
loop
Read (Root_Stream_Type'Class (Input_Stream.all), Buffer, N);
Count_Words (Buffer (1 .. N));
exit when N < Buffer'Length;
end loop;
Ada.Text_IO.Put_Line
(Natural'Image (Lines) &
Natural'Image (Words) &
Natural'Image (Total));
end;