152 lines
4.2 KiB
Ada
152 lines
4.2 KiB
Ada
Pragma Ada_2012;
|
|
Pragma Assertion_Policy( Check );
|
|
|
|
With
|
|
Unchecked_Conversion,
|
|
Ada.Text_IO;
|
|
|
|
Procedure Test_Roman_Numerals is
|
|
|
|
-- We create an enumeration of valid characters, note that they are
|
|
-- character-literals, this is so that we can use literal-strings,
|
|
-- and that their size is that of Integer.
|
|
Type Roman_Digits is ('I', 'V', 'X', 'L', 'C', 'D', 'M' )
|
|
with Size => Integer'Size;
|
|
|
|
-- We use a representation-clause ensure the proper integral-value
|
|
-- of each individual character.
|
|
For Roman_Digits use
|
|
(
|
|
'I' => 1,
|
|
'V' => 5,
|
|
'X' => 10,
|
|
'L' => 50,
|
|
'C' => 100,
|
|
'D' => 500,
|
|
'M' => 1000
|
|
);
|
|
|
|
-- To convert a Roman_Digit to an integer, we now only need to
|
|
-- read its value as an integer.
|
|
Function Convert is new Unchecked_Conversion
|
|
( Source => Roman_Digits, Target => Integer );
|
|
|
|
-- Romena_Numeral is a string of Roman_Digit.
|
|
Type Roman_Numeral is array (Positive range <>) of Roman_Digits;
|
|
|
|
-- The Numeral_List type is used herein only for testing
|
|
-- and verification-data.
|
|
Type Numeral_List is array (Positive range <>) of
|
|
not null access Roman_Numeral;
|
|
|
|
-- The Test_Cases subtype ensures that Test_Data and Validation_Data
|
|
-- both contain the same number of elements, and that the indecies
|
|
-- are the same; essentially the same as:
|
|
--
|
|
-- pragma Assert( Test_Data'Length = Validation_Data'Length
|
|
-- AND Test_Data'First = Validation_Data'First);
|
|
|
|
subtype Test_Cases is Positive range 1..14;
|
|
|
|
Test_Data : constant Numeral_List(Test_Cases):=
|
|
(
|
|
New Roman_Numeral'("III"), -- 3
|
|
New Roman_Numeral'("XXX"), -- 30
|
|
New Roman_Numeral'("CCC"), -- 300
|
|
New Roman_Numeral'("MMM"), -- 3000
|
|
|
|
New Roman_Numeral'("VII"), -- 7
|
|
New Roman_Numeral'("LXVI"), -- 66
|
|
New Roman_Numeral'("CL"), -- 150
|
|
New Roman_Numeral'("MCC"), -- 1200
|
|
|
|
New Roman_Numeral'("IV"), -- 4
|
|
New Roman_Numeral'("IX"), -- 9
|
|
New Roman_Numeral'("XC"), -- 90
|
|
|
|
New Roman_Numeral'("ICM"), -- 901
|
|
New Roman_Numeral'("CIM"), -- 899
|
|
|
|
New Roman_Numeral'("MDCLXVI") -- 1666
|
|
);
|
|
|
|
Validation_Data : constant array(Test_Cases) of Natural:=
|
|
( 3, 30, 300, 3000,
|
|
7, 66, 150, 1200,
|
|
4, 9, 90,
|
|
901, 899,
|
|
1666
|
|
);
|
|
|
|
|
|
-- In Roman numerals, the subtractive form [IV = 4] was used
|
|
-- very infrequently, the most common form was the addidive
|
|
-- form [IV = 6]. (Consider military logistics and squads.)
|
|
|
|
-- SUM returns the Number, read in the additive form.
|
|
Function Sum( Number : Roman_Numeral ) return Natural is
|
|
begin
|
|
Return Result : Natural:= 0 do
|
|
For Item of Number loop
|
|
Result:= Result + Convert( Item );
|
|
end loop;
|
|
End Return;
|
|
end Sum;
|
|
|
|
-- EVAL returns Number read in the subtractive form.
|
|
Function Eval( Number : Roman_Numeral ) return Natural is
|
|
Current : Roman_Digits:= 'I';
|
|
begin
|
|
Return Result : Natural:= 0 do
|
|
For Item of Number loop
|
|
if Current < Item then
|
|
Result:= Convert(Item) - Result;
|
|
Current:= Item;
|
|
else
|
|
Result:= Result + Convert(Item);
|
|
end if;
|
|
end loop;
|
|
End Return;
|
|
end Eval;
|
|
|
|
-- Display the given Roman_Numeral via Text_IO.
|
|
Procedure Put( S: Roman_Numeral ) is
|
|
begin
|
|
For Ch of S loop
|
|
declare
|
|
-- The 'Image attribute returns the character inside
|
|
-- single-quotes; so we select the character itself.
|
|
C : Character renames Roman_Digits'Image(Ch)(2);
|
|
begin
|
|
Ada.Text_IO.Put( C );
|
|
end;
|
|
end loop;
|
|
end;
|
|
|
|
-- This displays pass/fail dependant on the parameter.
|
|
Function PF ( Value : Boolean ) Return String is
|
|
begin
|
|
Return Result : String(1..4):= ( if Value then"pass"else"fail" );
|
|
End PF;
|
|
|
|
Begin
|
|
Ada.Text_IO.Put_Line("Starting Test:");
|
|
|
|
for Index in Test_Data'Range loop
|
|
declare
|
|
Item : Roman_Numeral renames Test_Data(Index).all;
|
|
Value : constant Natural := Eval(Item);
|
|
begin
|
|
Put( Item );
|
|
|
|
Ada.Text_IO.Put( ASCII.HT & "= ");
|
|
Ada.Text_IO.Put( Value'Img );
|
|
Ada.Text_IO.Put_Line( ASCII.HT & '[' &
|
|
PF( Value = Validation_Data(Index) )& ']');
|
|
end;
|
|
end loop;
|
|
|
|
|
|
Ada.Text_IO.Put_Line("Testing complete.");
|
|
End Test_Roman_Numerals;
|