Task: Roman numerals_Decode

C: #include <stdio.h>

int digits[26] = { 0, 0, 100, 500, 0, 0, 0, 0, 1, 1, 0, 50, 1000, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 10, 0, 0 };


#define VALUE(x) digits[(~0x20 & (x)) - 'A']

int decode(const char * roman)
{
        const char *bigger;
        int current;
        int arabic = 0;
        while (*roman != '\0') {
                current = VALUE(*roman);
                
                bigger = roman;

                
                while (VALUE(*bigger) <= current && *++bigger != '\0');

                if (*bigger == '\0')
                        arabic += current;
                else {
                        arabic += VALUE(*bigger);
                        while (roman < bigger)
                                arabic -= VALUE(* (roman++) );
                }

                roman ++;
        }
        return arabic;
}

int main()
{
        const char * romans[] = { "MCmxC", "MMVIII", "MDClXVI", "MCXLUJ" };
        int i;

        for (i = 0; i < 4; i++)
                printf("%s\t%d\n", romans[i], decode(romans[i]));

        return 0;
}











Ada: Pragma Ada_2012;
Pragma Assertion_Policy( Check );

With
Unchecked_Conversion,
Ada.Text_IO;

Procedure Test_Roman_Numerals is

    
    
    
    Type Roman_Digits is ('I', 'V', 'X', 'L', 'C', 'D', 'M' )
    with Size => Integer'Size;

    
    
    For Roman_Digits use
      (
    'I' => 1,
    'V' => 5,
    'X' => 10,
    'L' => 50,
    'C' => 100,
    'D' => 500,
    'M' => 1000
      );

    
    
    Function Convert is new Unchecked_Conversion
      (	Source => Roman_Digits,	Target => Integer );

    
    Type Roman_Numeral is array (Positive range <>) of Roman_Digits;

    
    
    Type Numeral_List is array (Positive range <>) of
      not null access Roman_Numeral;

    
    
    
    
    
    

    subtype Test_Cases is Positive range 1..14;

    Test_Data : constant Numeral_List(Test_Cases):=
      (
       New Roman_Numeral'("III"),	
       New Roman_Numeral'("XXX"),	
       New Roman_Numeral'("CCC"),	
       New Roman_Numeral'("MMM"),	

       New Roman_Numeral'("VII"),	
       New Roman_Numeral'("LXVI"),	
       New Roman_Numeral'("CL"),	
       New Roman_Numeral'("MCC"),	

       New Roman_Numeral'("IV"),	
       New Roman_Numeral'("IX"),	
       New Roman_Numeral'("XC"),	

       New Roman_Numeral'("ICM"),	
       New Roman_Numeral'("CIM"),	
       
       New Roman_Numeral'("MDCLXVI")	
      );

    Validation_Data : constant array(Test_Cases) of Natural:=
      (	3, 30, 300, 3000,
	7, 66, 150, 1200,
	4, 9, 90,
	901, 899,
	1666
      );


    
    
    

    
    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;

    
    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;

    
    Procedure Put( S: Roman_Numeral ) is
    begin
	For Ch of S loop
	    declare
		
		
		C : Character renames Roman_Digits'Image(Ch)(2);
	    begin
		Ada.Text_IO.Put( C );
	    end;
	end loop;
    end;

    
    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;