Roman numerals/Encode
You are encouraged to solve this task according to the task description, using any language you may know.
Create a function taking a positive integer as its parameter and returning a string containing the Roman Numeral representation of that integer.
Modern Roman numerals are written by expressing each digit separately starting with the left most digit and skipping any digit with a value of zero. In Roman numerals 1990 is rendered: 1000=M, 900=CM, 90=XC; resulting in MCMXC. 2008 is written as 2000=MM, 8=VIII; or MMVIII. 1666 uses each Roman symbol in descending order: MDCLXVI.
Ada
<Ada> with Ada.Text_Io; use Ada.Text_Io; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
procedure Roman_Numeral_Test is
function To_Roman(Number : Positive) return String is Result : Unbounded_String; Current_Value : Natural := Number; begin if Current_Value >= 1000 then Result := Result & ((Current_Value / 1000) * 'M'); Current_Value := Current_Value mod 1000; end if; if Current_Value >= 900 then Result := Result & "CM"; Current_Value := Current_Value mod 900; end if; if Current_Value >= 500 then Result := Result & "D"; Current_Value := Current_Value mod 500; end if; if Current_Value >= 100 then Result := Result & ((Current_Value / 100) * 'C'); Current_Value := Current_Value mod 100; end if; if Current_Value >= 90 then Result := Result & "XC"; Current_Value := Current_Value mod 90; end if; if Current_Value >= 50 then Result := Result & "L"; Current_Value := Current_Value mod 50; end if; if Current_Value >= 40 then Result := Result & "XL"; Current_Value := Current_Value mod 40; end if; if Current_Value >= 10 then Result := Result & ((Current_Value / 10) * 'X'); Current_Value := Current_Value mod 10; end if; if Current_Value = 9 then Result := Result & "IX"; Current_Value := 0; end if; if Current_Value >= 5 then Result := Result & "V"; Current_Value := Current_Value mod 5; end if; if Current_Value = 4 then Result := Result & "IV"; Current_Value := 0; end if; Result := Result & (Current_Value * 'I'); return To_String(Result); end To_Roman;
begin
Put_Line(To_Roman(1999)); Put_Line(To_Roman(25)); Put_Line(To_Roman(944));
end Roman_Numeral_Test; </Ada> Output:
MCMXCIX XXV CMXLIV
Haskell
With an explicit decimal digit representation list:
digit x y z k = [[x],[x,x],[x,x,x],[x,y],[y],[y,x],[y,x,x],[y,x,x,x],[x,z]] !! (fromInteger k - 1) toRoman :: Integer -> String toRoman 0 = "" toRoman x | x < 0 = error "Negative roman numeral" toRoman x | x >= 1000 = 'M' : toRoman (x - 1000) toRoman x | x >= 100 = digit 'C' 'D' 'M' q ++ toRoman r where (q,r) = x `divMod` 100 toRoman x | x >= 10 = digit 'X' 'L' 'C' q ++ toRoman r where (q,r) = x `divMod` 10 toRoman x = digit 'I' 'V' 'X' x
Output:
*Main> map toRoman [1999,25,944] ["MCMXCIX","XXV","CMXLIV"]
J
rfd obtains Roman numerals from decimals, and dfr decimals from Roman numerals.
dfr=: 3 : 0 i=. 'IVXLCDM' i. y d=. i{1 5 10 50 100 500 1000 +/d*_1^i<}.i,_1 ) r100 =. <;._1 ' C CC CCC CD D DC DCC DCCC CM' r10 =. <;._1 ' X XX XXX XL L LX LXX LXXX XC' r1 =. <;._1 ' I II III IV V VI VII VIII IX' R1000=: , r100 ,&.>/ r10 ,&.>/ r1 rfd=: 3 : 0 ('M'$~<.y%1000),R1000{::~1000|y )
Copied, with permission, from the J Wiki. Examples of use will be found there.
Java
The helper function copies is added since Java does not support String multiplication. The conversion function returns null for a negative number, since Java does not have unsigned primitives. <java>public class RN{ public static void main(String args[]){ System.out.println(roman(1999)); System.out.println(roman(25)); System.out.println(roman(954)); } public static String roman(long n){ if(n < 1) return null; String result = ""; if(n >= 1000){ result+= (copies("M",(n / 1000))); n%= 1000; } if(n >= 900){ result+= "CM"; n%= 900; } if(n >= 500){ result+= "D"; n%= 500; } if(n >= 400){ result+= "CD"; n%= 400; } if(n >= 100){ result+= (copies("C",(n / 100))); n%= 100; } if(n >= 90){ result+= "XC"; n%= 90; } if(n >= 50){ result+= "L"; n%= 50; } if(n >= 40){ result+= "XL"; n%= 40; } if(n >= 10){ result+= (copies("X",(n / 10))); n%= 10; } if(n == 9){ result+= "IX"; n= 0; } if(n >= 5){ result+= "V"; n%= 5; } if(n == 4){ result+= "IV"; n= 0; } result+= (copies("I",n)); return result; }
public static String copies(String a, int n){ String result = ""; for(int i= 0;i < n;i++,result+= a); return result; } }</java> Output:
MCMXCIX XXV CMXLIV
Ruby
Roman numeral generation was used as an example for demonstrating Test Driven Development in Ruby.