Perform operations on Roman numerals


This program converts two roman numerals into integers, performs the user's
choice of calculation, and outputs the answer in roman.
------------------------------------------------------

with Ada.Text_IO;
use Ada.Text_IO;
with Ada.Integer_Text_IO;
use Ada.Integer_Text_IO;


procedure Roman is

-- Declare variables which will be used in main program out here

  LEN1 : Integer:=0; 
  LEN2 : Integer:=0; 

  MaxRomanLength : CONSTANT integer := 20;
  subtype RomanNumeralType is String(1..MaxRomanLength);

  RomanNumeral1 : RomanNumeralType;
  RomanNumeral2 : RomanNumeralType;
  
  Input1 : Integer:=0;
  Input2 : Integer:=0;
 
  UserChoice : Integer:=0;

  FinalInteger : Integer:=0;
  
--------------------------------------------------------------------------------
  
   -- Function for checking Valid Input from the user
   -- This function returns a boolean value
   Function ValidRomanNumeral (PossibleNumeral : RomanNumeralType) Return
Boolean is
         
         Position : Natural := 1; -- position we are checking in the input
         
      begin -- ValidRomanNumeral
         loop
            If Position = MaxRomanLength Then
               Return True;  -- we have reached the maximum length without
problems
            Elsif PossibleNumeral(Position) = ' ' Then
               Return True;   -- we have reached the actual end without
problems
            Elsif PossibleNumeral(Position) = 'I' OR
PossibleNumeral(Position) = 'V'
               OR PossibleNumeral(Position) = 'X' OR
PossibleNumeral(Position) = 'L'
               OR PossibleNumeral(Position) = 'C' OR
PossibleNumeral(Position) = 'D'
               OR PossibleNumeral(Position) = 'M' Then
                  Position := Position + 1;
            Else
               Return False;  -- we have a problem, so return false
            end if;
         end loop;
         -- This will never happen, but it makes the compiler happy.
         Return False;
      end ValidRomanNumeral;
   
--------------------------------------------------------------------------------

      -- Procedure for getting a valid roman numeral from the user   
      Procedure GetValidRomanNumeral (RomanNumeral1 : OUT RomanNumeralType;
                                      RomanNumeral2 : OUT RomanNumeralType)
is
                                      
         Length1 : Natural; -- Number of chars in first entry
         Length2 : Natural; -- Number of chars in second entry
         
      begin -- GetValidRomanNumeral
         loop 
            RomanNumeral1 := (others => ' ');
            RomanNumeral2 := (others => ' ');
            Put(Item =>"Please enter the FIRST Roman numeral: ");
            Get_Line(Item => RomanNumeral1, Last => Length1);
            
            Put(Item =>"Please enter the SECOND Roman numeral: ");
            Get_Line(Item => RomanNumeral2, Last => Length2);
            
            
            LEN1 := Length1;
            LEN2 := Length2;  
            
            -- Code to check the validity of the two user inputs
            --exit when ValidRomanNumeral1(PossibleNumeral1 =>
RomanNumeral1); AND
             --         ValidRomanNumeral2(PossibleNumeral2 =>
RomanNumeral2); 
                      
            
            If ValidRomanNumeral(PossibleNumeral=>RomanNumeral1) then
                  If ValidRomanNumeral(PossibleNumeral=>RomanNumeral2)
then
                           Exit;
                  end if;
            end if;      
                              
            Put(Item => "Please make sure BOTH the Roman Numerals are
valid and try again");
            New_Line;
         end loop;
      end GetValidRomanNumeral;

--------------------------------------------------------------------------------

Function RomanToNatural (RomanNumeral : RomanNumeralType) Return Natural is
      Result : Natural := 0;  -- result variable
      CurrentPosition : Natural := 1; -- the current position in
RomanNumeral being examined.
      Value : Integer:=0; -- Value of the corresponding roman numeral
      First  : Integer:=0;
      Next : Integer:=0;

     
   begin --RomanToNatural
      
      ProcessValue: -- Loop to process the appropriate value from the user
      Loop

         If RomanNumeral(CurrentPosition) = 'M' then
            Value := 1000;      
         elsif RomanNumeral(CurrentPosition) = 'D' then
            Value := 500;
         elsif RomanNumeral(CurrentPosition) = 'C' then
            Value := 100;
         elsif RomanNumeral(CurrentPosition) = 'L' then    
            Value := 50;
         elsif RomanNumeral(CurrentPosition) = 'X' then
            Value := 10;
         elsif RomanNumeral(CurrentPosition) = 'V' then
            Value := 5;
         elsif RomanNumeral(CurrentPosition) = 'I' then
            Value := 1;
         elsif RomanNumeral(CurrentPosition) = ' ' then
            
            exit;   
         end if;
                       
         -- If this is the first character then store the value
         -- of it in the variable 'First'
         If CurrentPosition = 1 then
            First := Value;        
         end if;   
         
         Next := Value; -- Store the second value in this variable(2nd
iteration)
         
         -- This is for the second Iteration. Check if the second value
         -- is greater than the first value and perform the nescassary
         -- steps. 
         if First < Next then
            Result := (Next - First) + (Result - First);
         else
            Result := Result + Next;
      end if;   
      
     -- Assign the value of first to next
     -- for comparison in later cases 
     First := Next;      
      
     CurrentPosition := CurrentPosition + 1; -- Increment the counter
Variable

     --exit when CurrentPosition = (LEN + 1); -- Exit the loop after the
last character is read
      
    
    end loop ProcessValue; -- End the loop here  
    
    Return Result; -- Return the final result to where function is being
called
    
   end RomanToNatural; -- End the function

--------------------------------------------------------------------------------
   -- This Function Gets a valid choice from the user
   -- The user can chooose to perform arithmetic operations on the 
   -- Roman numerals. The choices are 1 through 4. 
   -- Will keep looping till the user gives correct Choice
   Procedure GetValidChoice(ValidChoice : OUT Integer)is
   
    Choice : Integer:=1; 
       
    begin
       
      BotherUser: 
      loop
         New_Line;
         Put("Please choose one of the following operations to be
performed:");   
         New_line;
         Put("1) Add the two Roman Numerals.");
         New_line;
         Put("2) Subtract the two Roman Numerals.");
         New_Line;
         Put("3) Multiply the two Roman Numerals.1");
         New_Line;
         Put("4)Divide the two Roman Numerals.");
         New_Line;
         Put("----------------------------------------------------");
         New_Line;
         Put("Please enter choice:");
         Ada.Integer_Text_IO.Get(Item=>Choice);
         
         If (choice>0) or (choice<=4) then
            exit;
         else 
            New_Line;         
            Put("Please enter Valid Choice.");   
            New_Line;
         end if;      
      
      end loop BotherUser;
      
    ValidChoice := Choice;
     
   end GetValidChoice;
--------------------------------------------------------------------------------
   
   -- This procedure process the valid choice and performs the
   -- nescassary calculations on the Two user inputs
   Procedure ProcessChoice(UserInput1 : IN Integer;
                           UserInput2 : IN Integer;
                           Choice     : IN Integer;
                           Output     : OUT Integer) IS   
   
-- Write this procedure in the morning
-- what this essentially does is 
-- it takes in userinput1 and userinput2 and Choice as IN Variables
-- According to the user's specified choice we can then compute the
possible
-- values and return Output
-- This value of output will the in turn be stored in a variable called 
-- FinalInteger
      
      -- declare variables here
      
      Plus     : Integer:=0;
      Minus    : Integer:=0;
      Multiply : Integer:=0;
      Divide   : Integer:=0;
      
      
      begin -- ProcessChoice
      
      -- Start checking for user choice and perform nescassary action
            
      If (Choice = 1) then
      
         Plus := UserInput1 + UserInput2;
         Output := Plus;
         
      elsif (Choice = 2) then
         
         Minus := UserInput1 - UserInput2;
         Output := Minus;
         
      elsif (Choice = 3) then
         
         Multiply := UserInput1 * UserInput2;
         Output := Multiply;
         
      elsif (Choice = 4) then
         
         Divide := UserInput1 / UserInput2;
         Output := Divide;
      else
         put("SOMETHING HAS GONE WRONG");       
         
      end if;   
 
   end ProcessChoice;
-------------------------------------------------------------------------
   Procedure ConvertBack(ConvertWhat : IN Integer) is
         
     Value : Integer;     
     
    begin  
        
     Value := ConvertWhat;
     for I in 1..20 loop
        if Value<=4000 and Value>=1 then
        
               Ada.Text_Io.Put(Item => "Final Result is:");
               
               while Value>=1000 loop
               
                  Ada.Text_Io.Put(Item => "M");             
                  Value:=Value - 1000;
                  
               end loop;
               
               while Value>=500 loop
               
                  Ada.Text_Io.Put(Item => "D");
                  Value:=Value - 500;  
               end loop;
               
               while Value>=100 loop
                  Ada.Text_Io.Put(Item => "C");
                  Value:=Value - 100;
               end loop;
               
               while Value>=50 loop
                  Ada.Text_Io.Put(Item => "L");
                  Value:=Value - 50;
               end loop;
               
               while Value>=10 loop
                  Ada.Text_Io.Put(Item => "X");
                  Value:=Value - 10;
               end loop;
               
               while Value>=5 loop
                  Ada.Text_Io.Put(Item => "V");
                  Value:=Value - 5;
               end loop;
               
               while Value>=1 loop
                  Ada.Text_Io.Put(Item => "I");
                  Value:=Value - 1;
               end loop;                                 
               
            end if;
            Ada.Text_Io.New_Line;
         end loop;
   end ConvertBack;
--------------------------------------------------------------------------------
  begin -- Procedure Roman
  
  Put("Welcome to the Roman Numeral Calculator program:");
  New_Line(2);
  
  -- Get the valid roman numeral from the user
  -- This function returns two integer values in RomanInteger1 and
RomanInteger2
  -- These values are the corresponding integer values of the entered roman
numerals 
  GetValidRomanNumeral(RomanNumeral1=>RomanNumeral1,
RomanNumeral2=>RomanNumeral2);
     
  Input1 := RomanToNatural(RomanNumeral=>RomanNumeral1);
  Input2 := RomanToNatural(RomanNumeral=>RomanNumeral2);
  
  GetValidChoice(ValidChoice=>UserChoice);


ProcessChoice(UserInput1=>Input1,UserInput2=>Input2,Choice=>UserChoice,Output=>FinalInteger);
  
  ConvertBack(ConvertWhat=>FinalInteger);   
end Roman;  

Contributed by: Samir
Contributed on: December 7, 2001
License: Public Domain

Back