tasks a-s

This commit is contained in:
Ingy döt Net 2013-04-10 23:57:08 -07:00
parent 47bf37c096
commit b83f433714
12433 changed files with 156208 additions and 123 deletions

View file

@ -0,0 +1,3 @@
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.

View file

@ -0,0 +1,29 @@
[]CHAR roman = "MDCLXVmdclxvi"; # UPPERCASE for thousands #
[]CHAR adjust roman = "CCXXmmccxxii";
[]INT arabic = (1000000, 500000, 100000, 50000, 10000, 5000, 1000, 500, 100, 50, 10, 5, 1);
[]INT adjust arabic = (100000, 100000, 10000, 10000, 1000, 1000, 100, 100, 10, 10, 1, 1, 0);
PROC arabic to roman = (INT dclxvi)STRING: (
INT in := dclxvi; # 666 #
STRING out := "";
FOR scale TO UPB roman WHILE in /= 0 DO
INT multiples = in OVER arabic[scale];
in -:= arabic[scale] * multiples;
out +:= roman[scale] * multiples;
IF in >= -adjust arabic[scale] + arabic[scale] THEN
in -:= -adjust arabic[scale] + arabic[scale];
out +:= adjust roman[scale] + roman[scale]
FI
OD;
out
);
main:(
[]INT test = (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,25,30,40,50,60,69,70,
80,90,99,100,200,300,400,500,600,666,700,800,900,1000,1009,1444,1666,1945,1997,1999,
2000,2008,2500,3000,4000,4999,5000,6666,10000,50000,100000,500000,1000000,max int);
FOR key TO UPB test DO
INT val = test[key];
print((val, " - ", arabic to roman(val), new line))
OD
)

View file

@ -0,0 +1,51 @@
BEGIN
PROCEDURE ROMAN (INTEGER VALUE NUMBER; STRING(15) RESULT CHARACTERS; INTEGER RESULT LENGTH);
COMMENT
Returns the Roman number of an integer between 1 and 3999.
"MMMDCCCLXXXVIII" (15 characters long) is the longest Roman number under 4000;
BEGIN
INTEGER PLACE, POWER;
PROCEDURE APPEND (STRING(1) VALUE C);
BEGIN CHARACTERS(LENGTH|1) := C; LENGTH := LENGTH + 1 END;
PROCEDURE I; APPEND(CASE PLACE OF ("I","X","C","M"));
PROCEDURE V; APPEND(CASE PLACE OF ("V","L","D"));
PROCEDURE X; APPEND(CASE PLACE OF ("X","C","M"));
ASSERT (NUMBER >= 1) AND (NUMBER < 4000);
CHARACTERS := " ";
LENGTH := 0;
POWER := 1000;
PLACE := 4;
WHILE PLACE > 0 DO
BEGIN
CASE NUMBER DIV POWER + 1 OF BEGIN
BEGIN END;
BEGIN I END;
BEGIN I; I END;
BEGIN I; I; I END;
BEGIN I; V END;
BEGIN V END;
BEGIN V; I END;
BEGIN V; I; I END;
BEGIN V; I; I; I END;
BEGIN I; X END
END;
NUMBER := NUMBER REM POWER;
POWER := POWER DIV 10;
PLACE := PLACE - 1
END
END ROMAN;
INTEGER I;
STRING(15) S;
ROMAN(1, S, I); WRITE(S, I);
ROMAN(3999, S, I); WRITE(S, I);
ROMAN(3888, S, I); WRITE(S, I);
ROMAN(2009, S, I); WRITE(S, I);
ROMAN(405, S, I); WRITE(S, I);
END.

View file

@ -0,0 +1,26 @@
# syntax: GAWK -f ROMAN_NUMERALS_ENCODE.AWK
BEGIN {
leng = split("1990 2008 1666",arr," ")
for (i=1; i<=leng; i++) {
n = arr[i]
printf("%s = %s\n",n,dec2roman(n))
}
exit(0)
}
function dec2roman(number, v,w,x,y,roman1,roman10,roman100,roman1000) {
number = int(number) # force to integer
if (number < 1 || number > 3999) { # number is too small | big
return
}
split("I II III IV V VI VII VIII IX",roman1," ") # 1 2 ... 9
split("X XX XXX XL L LX LXX LXXX XC",roman10," ") # 10 20 ... 90
split("C CC CCC CD D DC DCC DCCC CM",roman100," ") # 100 200 ... 900
split("M MM MMM",roman1000," ") # 1000 2000 3000
v = (number - (number % 1000)) / 1000
number = number % 1000
w = (number - (number % 100)) / 100
number = number % 100
x = (number - (number % 10)) / 10
y = number % 10
return(roman1000[v] roman100[w] roman10[x] roman1[y])
}

View file

@ -0,0 +1,14 @@
function arabic2roman(num:Number):String {
var lookup:Object = {M:1000, CM:900, D:500, CD:400, C:100, XC:90, L:50, XL:40, X:10, IX:9, V:5, IV:4, I:1};
var roman:String = "", i:String;
for (i in lookup) {
while (num >= lookup[i]) {
roman += i;
num -= lookup[i];
}
}
return roman;
}
trace("1990 in roman is " + arabic2roman(1990));
trace("2008 in roman is " + arabic2roman(2008));
trace("1666 in roman is " + arabic2roman(1666));

View file

@ -0,0 +1,13 @@
function roman2arabic(roman:String):Number {
var romanArr:Array = roman.toUpperCase().split('');
var lookup:Object = {I:1, V:5, X:10, L:50, C:100, D:500, M:1000};
var num:Number = 0, val:Number = 0;
while (romanArr.length) {
val = lookup[romanArr.shift()];
num += val * (val < lookup[romanArr[0]] ? -1 : 1);
}
return num;
}
trace("MCMXC in arabic is " + roman2arabic("MCMXC"));
trace("MMVIII in arabic is " + roman2arabic("MMVIII"));
trace("MDCLXVI in arabic is " + roman2arabic("MDCLXVI"));

View file

@ -0,0 +1,33 @@
with Ada.Text_IO; use Ada.Text_IO;
procedure Roman_Numeral_Test is
function To_Roman (Number : Positive) return String is
subtype Digit is Integer range 0..9;
function Roman (Figure : Digit; I, V, X : Character) return String is
begin
case Figure is
when 0 => return "";
when 1 => return "" & I;
when 2 => return I & I;
when 3 => return I & I & I;
when 4 => return I & V;
when 5 => return "" & V;
when 6 => return V & I;
when 7 => return V & I & I;
when 8 => return V & I & I & I;
when 9 => return I & X;
end case;
end Roman;
begin
pragma Assert (Number >= 1 and Number < 4000);
return
Roman (Number / 1000, 'M', ' ', ' ') &
Roman (Number / 100 mod 10, 'C', 'D', 'M') &
Roman (Number / 10 mod 10, 'X', 'L', 'C') &
Roman (Number mod 10, 'I', 'V', 'X');
end To_Roman;
begin
Put_Line (To_Roman (1999));
Put_Line (To_Roman (25));
Put_Line (To_Roman (944));
end Roman_Numeral_Test;

View file

@ -0,0 +1,28 @@
MsgBox % stor(444)
stor(value)
{
romans = M,CM,D,CD,C,XC,L,XL,X,IX,V,IV,I
M := 1000
CM := 900
D := 500
CD := 400
C := 100
XC := 90
L := 50
XL := 40
X := 10
IX := 9
V := 5
IV := 4
I := 1
Loop, Parse, romans, `,
{
While, value >= %A_LoopField%
{
result .= A_LoopField
value := value - (%A_LoopField%)
}
}
Return result . "O"
}

View file

@ -0,0 +1,20 @@
DIM SHARED arabic(0 TO 12) AS Integer => {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 }
DIM SHARED roman(0 TO 12) AS String*2 => {"M", "CM", "D","CD", "C","XC","L","XL","X","IX","V","IV","I"}
FUNCTION toRoman(value AS Integer) AS String
DIM i AS Integer
DIM result AS String
FOR i = 0 TO 12
DO WHILE value >= arabic(i)
result = result + roman(i)
value = value - arabic(i)
LOOP
NEXT i
toRoman = result
END FUNCTION
'Testing
PRINT "2009 = "; toRoman(2009)
PRINT "1666 = "; toRoman(1666)
PRINT "3888 = "; toRoman(3888)

View file

@ -0,0 +1,17 @@
10 DATA 1000,"M",900,"CM"
20 DATA 500,"D",400,"CD"
30 DATA 100,"C",90,"XC"
40 DATA 50,"L",40,"XL"
50 DATA 10,"X",9,"IX"
60 DATA 5,"V",4,"IV",1,"I"
70 INPUT "Enter an arabic number: ";V
80 LET VALUE=V
90 LET V$=""
100 FOR I=0 TO 12
110 READ A,R$
120 IF V<A THEN GO TO 160
130 LET V$=V$+R$
140 LET V=V-A
150 GO TO 120
160 NEXT I
170 PRINT VALUE;"=";V$

View file

@ -0,0 +1,16 @@
print 1666+" = "+convert$(1666)
print 2008+" = "+convert$(2008)
print 1001+" = "+convert$(1001)
print 1999+" = "+convert$(1999)
function convert$(value)
convert$=""
arabic = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 }
roman$ = {"M", "CM", "D","CD", "C","XC","L","XL","X","IX","V","IV","I"}
for i = 0 to 12
while value >= arabic[i]
convert$ += roman$[i]
value = value - arabic[i]
end while
next i
end function

View file

@ -0,0 +1,18 @@
PRINT ;1999, FNroman(1999)
PRINT ;2012, FNroman(2012)
PRINT ;1666, FNroman(1666)
PRINT ;3888, FNroman(3888)
END
DEF FNroman(n%)
LOCAL i%, r$, arabic%(), roman$()
DIM arabic%(12), roman$(12)
arabic%() = 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900,1000
roman$() = "I","IV", "V","IX", "X","XL", "L","XC", "C","CD", "D","CM", "M"
FOR i% = 12 TO 0 STEP -1
WHILE n% >= arabic%(i%)
r$ += roman$(i%)
n% -= arabic%(i%)
ENDWHILE
NEXT
= r$

View file

@ -0,0 +1,49 @@
( ( encode
= indian roman cifr tenfoldroman letter tenfold
. !arg:#?indian
& :?roman
& whl
' ( @(!indian:#%?cifr ?indian)
& :?tenfoldroman
& whl
' ( !roman:%?letter ?roman
& !tenfoldroman
( (I.X)
(V.L)
(X.C)
(L.D)
(C.M)
: ? (!letter.?tenfold) ?
& !tenfold
| "*"
)
: ?tenfoldroman
)
& !tenfoldroman:?roman
& ( !cifr:9&!roman I X:?roman
| !cifr:~<4
& !roman
(!cifr:4&I|)
V
: ?roman
& !cifr+-5:?cifr
& ~
| whl
' ( !cifr+-1:~<0:?cifr
& !roman I:?roman
)
)
)
& ( !roman:? "*" ?&~`
| str$!roman
)
)
& 1990 2008 1666 3888 3999 4000:?NS
& whl
' ( !NS:%?N ?NS
& out
$ ( encode$!N:?K&!N !K
| str$("Can't convert " !N " to Roman numeral")
)
)
);

View file

@ -0,0 +1,41 @@
#include <iostream>
#include <string>
std::string to_roman(int value)
{
struct romandata_t { int value; char const* numeral; };
static romandata_t const romandata[] =
{ 1000, "M",
900, "CM",
500, "D",
400, "CD",
100, "C",
90, "XC",
50, "L",
40, "XL",
10, "X",
9, "IX",
5, "V",
4, "IV",
1, "I",
0, NULL }; // end marker
std::string result;
for (romandata_t const* current = romandata; current->value > 0; ++current)
{
while (value >= current->value)
{
result += current->numeral;
value -= current->value;
}
}
return result;
}
int main()
{
for (int i = 1; i <= 4000; ++i)
{
std::cout << to_roman(i) << std::endl;
}
}

View file

@ -0,0 +1,59 @@
#include <stdlib.h>
#include <stdio.h>
/*
* Writes the Roman numeral representing n into the buffer s.
* Handles up to n = 3999.
* Since C doesn't have exceptions, n = 0 causes the whole program to exit
* unsuccessfully.
* s should be have room for at least 16 characters, including the trailing
* null.
*/
void roman(char *s, unsigned int n)
{
if (n == 0)
{
fputs(stderr, "Roman numeral for zero requested.");
exit(EXIT_FAILURE);
}
#define digit(loop, num, c) \
loop (n >= num) \
{*(s++) = c; \
n -= num;}
#define digits(loop, num, c1, c2) \
loop (n >= num) \
{*(s++) = c1; \
*(s++) = c2; \
n -= num;}
digit ( while, 1000, 'M' )
digits ( if, 900, 'C', 'M' )
digit ( if, 500, 'D' )
digits ( if, 400, 'C', 'D' )
digit ( while, 100, 'C' )
digits ( if, 90, 'X', 'C' )
digit ( if, 50, 'L' )
digits ( if, 40, 'X', 'L' )
digit ( while, 10, 'X' )
digits ( if, 9, 'I', 'X' )
digit ( if, 5, 'V' )
digits ( if, 4, 'I', 'V' )
digit ( while, 1, 'I' )
#undef digit
#undef digits
*s = 0;}
int main(void)
{
char buffer[16];
unsigned int i;
for (i = 1 ; i < 4000 ; ++i)
{
roman(buffer, i);
printf("%4u: %s\n", i, buffer);
}
return EXIT_SUCCESS;
}

View file

@ -0,0 +1,38 @@
char *ToRoman(int num, char *buf, int buflen)
{
static const char romanDgts[] = "ivxlcdmVXLCDM_";
char *roman = buf + buflen;
int rdix, r, v;
*--roman = '\0'; /* null terminate return string */
if (num >= 4000000) {
printf("Number Too Big.\n");
return NULL;
}
for (rdix = 0; rdix < strlen(romanDgts); rdix += 2) {
if (num == 0) break;
v = (num % 10) / 5;
r = num % 5;
num = num / 10;
if (r == 4) {
if (roman < buf+2) {
printf("Buffer too small.");
return NULL;
}
*--roman = romanDgts[rdix+1+v];
*--roman = romanDgts[rdix];
}
else {
if (roman < buf+r+v) {
printf("Buffer too small.");
return NULL;
}
while(r-- > 0) {
*--roman = romanDgts[rdix];
}
if (v==1) {
*--roman = romanDgts[rdix+1];
}
}
}
return roman;
}

View file

@ -0,0 +1,40 @@
#include <stdio.h>
int to_roman(char *out, int n)
{
int len = 0;
if (n <= 0) return 0; /* error indication */
# define RPUT(c) if (out) out[len] = c; len++
while(n>= 1000) { n -= 1000;RPUT('M'); };
if (n >= 900) { n -= 900; RPUT('C'); RPUT('M'); };
if (n >= 500) { n -= 500; RPUT('D'); };
if (n >= 400) { n -= 400; RPUT('C'); RPUT('D'); };
while (n >= 100){ n -= 100; RPUT('C'); };
if (n >= 90) { n -= 90; RPUT('X'); RPUT('C'); };
if (n >= 50) { n -= 50; RPUT('L'); };
if (n >= 40) { n -= 40; RPUT('X'); RPUT('L'); };
while (n >= 10) { n -= 10; RPUT('X'); };
if (n >= 9) { n -= 9; RPUT('I'); RPUT('X'); };
if (n >= 5) { n -= 5; RPUT('V'); };
if (n >= 4) { n -= 4; RPUT('I'); RPUT('V'); };
while (n) { n--; RPUT('I'); };
RPUT('\0');
# undef RPUT
return len;
}
int main()
{
char buf[16];
int d = to_roman(buf, 1666);
printf("roman for 1666 is %d bytes: %s\n", d, buf);
d = 68999123;
printf("%d would have required %d bytes\n", d, to_roman(0, d));
return 0;
}

View file

@ -0,0 +1,7 @@
(def arabic->roman
(partial clojure.pprint/cl-format nil "~@R"))
(arabic->roman 147)
;"CXXIII"
(arabic->roman 99)
;"XCIX"

View file

@ -0,0 +1,31 @@
(def arabic-roman-map
{1 "I", 5 "V",
10 "X", 50 "L",
100 "C", 500 "D",
1000 "M",
4 "IV", 9 "IX",
40 "XL", 90 "XC",
400 "CD", 900 "CM" })
(def arabic-roman-map-sorted-keys
(sort (keys arabic-roman-map)))
(defn find-value-in-coll
[coll k]
(let [aval (find coll k)]
(if (nil? aval) "" (val aval))))
(defn to-roman
[result n]
(let
[closest-key-for-n (last (filter #(> n %) arabic-roman-map-sorted-keys))
roman-value-for-n (find-value-in-coll arabic-roman-map n)
roman-value-for-closet-to-n (find-value-in-coll arabic-roman-map
closest-key-for-n)]
(if (or (<= n 0)(contains? arabic-roman-map n))
(conj result roman-value-for-n)
(recur (conj result roman-value-for-closet-to-n)
(- n closest-key-for-n)))))
Usage: >(to-roman [] 1999)
result: ["M" "CM" "XC" "IX"]

View file

@ -0,0 +1,17 @@
(defn a2r
[a]
(let [rv [1000 500 100 50 10 5 1]
rm (zipmap rv "MDCLXVI")
dv (->> rv (take-nth 2) next (#(interleave % %)))]
(loop [a a rv rv dv dv r nil]
(if (<= a 0)
r
(let [v (first rv)
d (or (first dv) 0)
l (- v d)]
(cond
(= a v) (str r (rm v))
(= a l) (str r (rm d) (rm v))
(and (> a v) (> a l)) (recur (- a v) rv dv (str r (rm v)))
(and (< a v) (< a l)) (recur a (rest rv) (rest dv) r)
:else (recur (- a l) (rest rv) (rest dv) (str r (rm d) (rm v)))))))))

View file

@ -0,0 +1,5 @@
(a2r 1666)
"MDCLXVI"
(map a2r [1000 1 389 45])
("M" "I" "CCCLXXXIX" "XLV")

View file

@ -0,0 +1,46 @@
decimal_to_roman = (n) ->
# This should work for any positive integer, although it
# gets a bit preposterous for large numbers.
if n >= 4000
thousands = decimal_to_roman n / 1000
ones = decimal_to_roman n % 1000
return "M(#{thousands})#{ones}"
s = ''
translate_each = (min, roman) ->
while n >= min
n -= min
s += roman
translate_each 1000, "M"
translate_each 900, "CM"
translate_each 500, "D"
translate_each 400, "CD"
translate_each 100, "C"
translate_each 90, "XC"
translate_each 50, "L"
translate_each 40, "XL"
translate_each 10, "X"
translate_each 9, "IX"
translate_each 5, "V"
translate_each 4, "IV"
translate_each 1, "I"
s
###################
tests =
IV: 4
XLII: 42
MCMXC: 1990
MMVIII: 2008
MDCLXVI: 1666
'M(IV)': 4000
'M(VI)IX': 6009
'M(M(CXXIII)CDLVI)DCCLXXXIX': 123456789
'M(MMMV)I': 3005001
for expected, decimal of tests
roman = decimal_to_roman(decimal)
if roman == expected
console.log "#{decimal} = #{roman}"
else
console.log "error for #{decimal}: #{roman} is wrong"

View file

@ -0,0 +1,2 @@
(defun roman-numeral (n)
(format nil "~@R" n))

View file

@ -0,0 +1,26 @@
string toRoman(int n) pure nothrow
in {
assert(n < 5000);
} body {
static immutable weights = [1000, 900, 500, 400, 100, 90,
50, 40, 10, 9, 5, 4, 1];
static immutable symbols = ["M","CM","D","CD","C","XC","L",
"XL","X","IX","V","IV","I"];
string roman;
foreach (i, w; weights) {
while (n >= w) {
roman ~= symbols[i];
n -= w;
}
if (n == 0)
break;
}
return roman;
} unittest {
assert(toRoman(455) == "CDLV");
assert(toRoman(3456) == "MMMCDLVI");
assert(toRoman(2488) == "MMCDLXXXVIII");
}
void main() {}

View file

@ -0,0 +1,20 @@
const weights = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
const symbols = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"];
function toRoman(n : Integer) : String;
var
i, w : Integer;
begin
for i := 0 to weights.High do begin
w := weights[i];
while n >= w do begin
Result += symbols[i];
n -= w;
end;
if n = 0 then Break;
end;
end;
PrintLn(toRoman(455));
PrintLn(toRoman(3456));
PrintLn(toRoman(2488));

View file

@ -0,0 +1,28 @@
program RomanNumeralsEncode;
{$APPTYPE CONSOLE}
function IntegerToRoman(aValue: Integer): string;
var
i: Integer;
const
WEIGHTS: array[0..12] of Integer = (1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1);
SYMBOLS: array[0..12] of string = ('M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I');
begin
for i := Low(WEIGHTS) to High(WEIGHTS) do
begin
while aValue >= WEIGHTS[i] do
begin
Result := Result + SYMBOLS[i];
aValue := aValue - WEIGHTS[i];
end;
if aValue = 0 then
Break;
end;
end;
begin
Writeln(IntegerToRoman(1990)); // MCMXC
Writeln(IntegerToRoman(2008)); // MMVIII
Writeln(IntegerToRoman(1666)); // MDCLXVI
end.

View file

@ -0,0 +1,17 @@
(defun ar2ro (AN)
"translate from arabic number AN to roman number,
ar2ro(1666) returns (M D C L X V I)"
(cond
((>= AN 1000) (cons 'M (ar2ro (- AN 1000))))
((>= AN 900) (cons 'C (cons 'M (ar2ro (-AN 900)))))
((>= AN 500) (cons 'D (ar2ro (- AN 500))))
((>= AN 400) (cons 'C (cons 'D (ar2ro (- AN 400)))))
((>= AN 100) (cons 'C (ar2ro (- AN 100))))
((>= AN 90) (cons 'X (cons 'C (ar2ro (- AN 90)))))
((>= AN 50) (cons 'L (ar2ro (- AN 50))))
((>= AN 40) (cons 'X (cons 'L (ar2ro (- AN 40)))))
((>= AN 10) (cons 'X (ar2ro (- AN 10))))
((>= AN 5) (cons 'V (ar2ro (- AN 5))))
((>= AN 4) (cons 'I (cons 'V (ar2ro (- AN 4)))))
((>= AN 1) (cons 'I (ar2ro (- AN 1))))
((= AN 0) nil)))

View file

@ -0,0 +1,20 @@
-module(roman).
-export([to_roman/1]).
to_roman(0) -> [];
to_roman(X) when X >= 1000 -> [$M | to_roman(X - 1000)];
to_roman(X) when X >= 100 ->
digit(X div 100, $C, $D, $M) ++ to_roman(X rem 100);
to_roman(X) when X >= 10 ->
digit(X div 10, $X, $L, $C) ++ to_roman(X rem 10);
to_roman(X) when X >= 1 -> digit(X, $I, $V, $X).
digit(1, X, _, _) -> [X];
digit(2, X, _, _) -> [X, X];
digit(3, X, _, _) -> [X, X, X];
digit(4, X, Y, _) -> [X, Y];
digit(5, _, Y, _) -> [Y];
digit(6, X, Y, _) -> [Y, X];
digit(7, X, Y, _) -> [Y, X, X];
digit(8, X, Y, _) -> [Y, X, X, X];
digit(9, X, _, Z) -> [X, Z].

View file

@ -0,0 +1,18 @@
constant arabic = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 }
constant roman = {"M", "CM", "D","CD", "C","XC","L","XL","X","IX","V","IV","I"}
function toRoman(integer val)
sequence result
result = ""
for i = 1 to 13 do
while val >= arabic[i] do
result &= roman[i]
val -= arabic[i]
end while
end for
return result
end function
printf(1,"%d = %s\n",{2009,toRoman(2009)})
printf(1,"%d = %s\n",{1666,toRoman(1666)})
printf(1,"%d = %s\n",{3888,toRoman(3888)})

View file

@ -0,0 +1,14 @@
^$." "
[$999>][1000- "M"]#
$899> [ 900-"CM"]?
$499> [ 500- "D"]?
$399> [ 400-"CD"]?
[$ 99>][ 100- "C"]#
$ 89> [ 90-"XC"]?
$ 49> [ 50- "L"]?
$ 39> [ 40-"XL"]?
[$ 9>][ 10- "X"]#
$ 8> [ 9-"IX"]?
$ 4> [ 5- "V"]?
$ 3> [ 4-"IV"]?
[$ ][ 1- "I"]#%

View file

@ -0,0 +1,3 @@
USE: roman
( scratchpad ) 3333 >roman .
"mmmcccxxxiii"

View file

@ -0,0 +1,16 @@
CONSTANT: roman-digits
{ "m" "cm" "d" "cd" "c" "xc" "l" "xl" "x" "ix" "v" "iv" "i" }
CONSTANT: roman-values
{ 1000 900 500 400 100 90 50 40 10 9 5 4 1 }
ERROR: roman-range-error n ;
: roman-range-check ( n -- n )
dup 1 10000 between? [ roman-range-error ] unless ;
: >roman ( n -- str )
roman-range-check
roman-values roman-digits [
[ /mod swap ] dip <repetition> concat
] 2map "" concat-as nip ;

View file

@ -0,0 +1,38 @@
**
** converts a number to its roman numeral representation
**
class RomanNumerals
{
private Str digit(Str x, Str y, Str z, Int i)
{
switch (i)
{
case 1: return x
case 2: return x+x
case 3: return x+x+x
case 4: return x+y
case 5: return y
case 6: return y+x
case 7: return y+x+x
case 8: return y+x+x+x
case 9: return x+z
}
return ""
}
Str toRoman(Int i)
{
if (i>=1000) { return "M" + toRoman(i-1000) }
if (i>=100) { return digit("C", "D", "M", i/100) + toRoman(i%100) }
if (i>=10) { return digit("X", "L", "C", i/10) + toRoman(i%10) }
if (i>=1) { return digit("I", "V", "X", i) }
return ""
}
Void main()
{
2000.times |i| { echo("$i = ${toRoman(i)}") }
}
}

View file

@ -0,0 +1,18 @@
: vector create ( n -- ) 0 do , loop does> ( n -- ) swap cells + @ execute ;
\ these are ( numerals -- numerals )
: ,I dup c@ C, ; : ,V dup 1 + c@ C, ; : ,X dup 2 + c@ C, ;
\ these are ( numerals -- )
:noname ,I ,X drop ; :noname ,V ,I ,I ,I drop ; :noname ,V ,I ,I drop ;
:noname ,V ,I drop ; :noname ,V drop ; :noname ,I ,V drop ;
:noname ,I ,I ,I drop ; :noname ,I ,I drop ; :noname ,I drop ;
' drop ( 0 : no output ) 10 vector ,digit
: roman-rec ( numerals n -- ) 10 /mod dup if >r over 2 + r> recurse else drop then ,digit ;
: roman ( n -- c-addr u )
dup 0 4000 within 0= abort" EX LIMITO!"
HERE SWAP s" IVXLCDM" drop swap roman-rec HERE OVER - ;
1999 roman type \ MCMXCIX
25 roman type \ XXV
944 roman type \ CMXLIV

View file

@ -0,0 +1,19 @@
create romans 0 , 1 , 5 , 21 , 9 , 2 , 6 , 22 , 86 , 13 ,
does> swap cells + @ ;
: roman-digit ( a1 n1 a2 n2 -- a3)
drop >r romans
begin dup while tuck 4 mod 1- chars r@ + c@ over c! char+ swap 4 / repeat
r> drop drop
;
: (split) swap >r /mod r> swap ;
: >roman ( n1 a -- a n2)
tuck 1000 (split) s" M " roman-digit 100 (split) s" CDM" roman-digit
10 (split) s" XLC" roman-digit 1 (split) s" IVX" roman-digit nip over -
;
create (roman) 16 chars allot
1999 (roman) >roman type cr

View file

@ -0,0 +1,35 @@
program roman_numerals
implicit none
write (*, '(a)') roman (2009)
write (*, '(a)') roman (1666)
write (*, '(a)') roman (3888)
contains
function roman (n) result (r)
implicit none
integer, intent (in) :: n
integer, parameter :: d_max = 13
integer :: d
integer :: m
integer :: m_div
character (32) :: r
integer, dimension (d_max), parameter :: d_dec = &
& (/1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1/)
character (32), dimension (d_max), parameter :: d_rom = &
& (/'M ', 'CM', 'D ', 'CD', 'C ', 'XC', 'L ', 'XL', 'X ', 'IX', 'V ', 'IV', 'I '/)
r = ''
m = n
do d = 1, d_max
m_div = m / d_dec (d)
r = trim (r) // repeat (trim (d_rom (d)), m_div)
m = m - d_dec (d) * m_div
end do
end function roman
end program roman_numerals

View file

@ -0,0 +1,39 @@
package main
import "fmt"
var (
m0 = []string{"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"}
m1 = []string{"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"}
m2 = []string{"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"}
m3 = []string{"", "M", "MM", "MMM", "I̅V̅",
"V̅", "V̅I̅", "V̅I̅I̅", "V̅I̅I̅I̅", "I̅X̅"}
m4 = []string{"", "X̅", "X̅X̅", "X̅X̅X̅", "X̅L̅",
"L̅", "L̅X̅", "L̅X̅X̅", "L̅X̅X̅X̅", "X̅C̅"}
m5 = []string{"", "C̅", "C̅C̅", "C̅C̅C̅", "C̅D̅",
"D̅", "D̅C̅", "D̅C̅C̅", "D̅C̅C̅C̅", "C̅M̅"}
m6 = []string{"", "M̅", "M̅M̅", "M̅M̅M̅"}
)
func formatRoman(n int) (string, bool) {
if n < 1 || n >= 4e6 {
return "", false
}
// this is efficient in Go. the seven operands are evaluated,
// then a single allocation is made of the exact size needed for the result.
return m6[n/1e6] + m5[n%1e6/1e5] + m4[n%1e5/1e4] + m3[n%1e4/1e3] +
m2[n%1e3/1e2] + m1[n%100/10] + m0[n%10],
true
}
func main() {
// show three numbers mentioned in task descriptions
for _, n := range []int{1990, 2008, 1666} {
r, ok := formatRoman(n)
if ok {
fmt.Println(n, "==", r)
} else {
fmt.Println(n, "not representable")
}
}
}

View file

@ -0,0 +1,28 @@
symbols = [ 1:'I', 4:'IV', 5:'V', 9:'IX', 10:'X', 40:'XL', 50:'L', 90:'XC', 100:'C', 400:'CD', 500:'D', 900:'CM', 1000:'M' ]
def roman(arabic) {
def result = ""
symbols.keySet().sort().reverse().each {
while (arabic >= it) {
arabic-=it
result+=symbols[it]
}
}
return result
}
assert roman(1) == 'I'
assert roman(2) == 'II'
assert roman(4) == 'IV'
assert roman(8) == 'VIII'
assert roman(16) == 'XVI'
assert roman(32) == 'XXXII'
assert roman(25) == 'XXV'
assert roman(64) == 'LXIV'
assert roman(128) == 'CXXVIII'
assert roman(256) == 'CCLVI'
assert roman(512) == 'DXII'
assert roman(954) == 'CMLIV'
assert roman(1024) == 'MXXIV'
assert roman(1666) == 'MDCLXVI'
assert roman(1990) == 'MCMXC'
assert roman(2008) == 'MMVIII'

View file

@ -0,0 +1,13 @@
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

View file

@ -0,0 +1,2 @@
*Main> map toRoman [1999,25,944]
["MCMXCIX","XXV","CMXLIV"]

View file

@ -0,0 +1,22 @@
CHARACTER Roman*20
CALL RomanNumeral(1990, Roman) ! MCMXC
CALL RomanNumeral(2008, Roman) ! MMVIII
CALL RomanNumeral(1666, Roman) ! MDCLXVI
END
SUBROUTINE RomanNumeral( arabic, roman)
CHARACTER roman
DIMENSION ddec(13)
DATA ddec/1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1/
roman = ' '
todo = arabic
DO d = 1, 13
DO rep = 1, todo / ddec(d)
roman = TRIM(roman) // TRIM(CHAR(d, 13, "M CM D CD C XC L XL X OX V IV I "))
todo = todo - ddec(d)
ENDDO
ENDDO
END

View file

@ -0,0 +1,6 @@
link numbers # commas, roman
procedure main(arglist)
every x := !arglist do
write(commas(x), " -> ",roman(x)|"*** can't convert to Roman numerals ***")
end

View file

@ -0,0 +1,12 @@
procedure roman(n) #: convert integer to Roman numeral
local arabic, result
static equiv
initial equiv := ["","I","II","III","IV","V","VI","VII","VIII","IX"]
integer(n) > 0 | fail
result := ""
every arabic := !n do
result := map(result,"IVXLCDM","XLCDM**") || equiv[arabic + 1]
if find("*",result) then fail else return result
end

View file

@ -0,0 +1,18 @@
Roman := Object clone do (
nums := list(1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1)
rum := list("M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I")
numeral := method(number,
result := ""
for(i, 0, nums size,
if(number == 0, break)
while(number >= nums at(i),
number = number - nums at(i)
result = result .. rum at(i)
)
)
return result
)
)
Roman numeral(1666) println

View file

@ -0,0 +1,7 @@
R1000=. ;L:1 ,{ <@(<;._1);._2]0 :0
C CC CCC CD D DC DCC DCCC CM
X XX XXX XL L LX LXX LXXX XC
I II III IV V VI VII VIII IX
)
rfd=: ('M' $~ <.@%&1000) , R1000 {::~ 1000&|

View file

@ -0,0 +1,6 @@
rfd 1234
MCCXXXIV
rfd 567
DLXVII
rfd 89
LXXXIX

View file

@ -0,0 +1,41 @@
public class RN {
enum Numeral {
I(1), IV(4), V(5), IX(9), X(10), XL(40), L(50), XC(90), C(100), CD(400), D(500), CM(900), M(1000);
int weight;
Numeral(int weight) {
this.weight = weight;
}
};
public static String roman(long n) {
if( n <= 0) {
throw new IllegalArgumentException();
}
StringBuilder buf = new StringBuilder();
final Numeral[] values = Numeral.values();
for (int i = values.length - 1; i >= 0; i--) {
while (n >= values[i].weight) {
buf.append(values[i]);
n -= values[i].weight;
}
}
return buf.toString();
}
public static void test(long n) {
System.out.println(n + " = " + roman(n));
}
public static void main(String[] args) {
test(1999);
test(25);
test(944);
test(0);
}
}

View file

@ -0,0 +1,18 @@
var roman = {
map: [
1000, 'M', 900, 'CM', 500, 'D', 400, 'CD', 100, 'C', 90, 'XC',
50, 'L', 40, 'XL', 10, 'X', 9, 'IX', 5, 'V', 4, 'IV', 1, 'I',
],
int_to_roman: function(n) {
var value = '';
for (var idx = 0; n > 0 && idx < this.map.length; idx += 2) {
while (n >= this.map[idx]) {
value += this.map[idx + 1];
n -= this.map[idx];
}
}
return value;
}
}
roman.int_to_roman(1999); // "MCMXCIX"

View file

@ -0,0 +1,5 @@
\documentclass{article}
\begin{document}
\newcounter{currentyear}\setcounter{currentyear}{\year}
Anno Domini \Roman{currentyear}
\end{document}

View file

@ -0,0 +1,31 @@
dim arabic( 12)
for i =0 to 12
read k
arabic( i) =k
next i
data 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1
dim roman$( 12)
for i =0 to 12
read k$
roman$( i) =k$
next i
data "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"
print 2009, toRoman$( 2009)
print 1666, toRoman$( 1666)
print 3888, toRoman$( 3888)
end
function toRoman$( value)
i =0
result$ =""
for i = 0 to 12
while value >=arabic( i)
result$ = result$ + roman$( i)
value = value - arabic( i)
wend
next i
toRoman$ =result$
end function

View file

@ -0,0 +1,12 @@
make "roman.rules [
[1000 M] [900 CM] [500 D] [400 CD]
[ 100 C] [ 90 XC] [ 50 L] [ 40 XL]
[ 10 X] [ 9 IX] [ 5 V] [ 4 IV]
[ 1 I]
]
to roman :n [:rules :roman.rules] [:acc "||]
if empty? :rules [output :acc]
if :n < first first :rules [output (roman :n bf :rules :acc)]
output (roman :n - first first :rules :rules word :acc last first :rules)
end

View file

@ -0,0 +1,18 @@
make "patterns [[?] [? ?] [? ? ?] [? ?2] [?2] [?2 ?] [?2 ? ?] [?2 ? ? ?] [? ?3]]
to digit :d :numerals
if :d = 0 [output "||]
output apply (sentence "\( "word (item :d :patterns) "\)) :numerals
end
to digits :n :numerals
output word ifelse :n < 10 ["||] [digits int :n/10 bf bf :numerals] ~
digit modulo :n 10 :numerals
end
to roman :n
if or :n < 0 :n >= 4000 [output [EX MODVS!]]
output digits :n [I V X L C D M]
end
print roman 1999 ; MCMXCIX
print roman 25 ; XXV
print roman 944 ; CMXLIV

View file

@ -0,0 +1,43 @@
Function toRoman(value) As String
Dim arabic(12) As Integer
Dim roman(12) As String
arabic(0) = 1000
arabic(1) = 900
arabic(2) = 500
arabic(3) = 400
arabic(4) = 100
arabic(5) = 90
arabic(6) = 50
arabic(7) = 40
arabic(8) = 10
arabic(9) = 9
arabic(10) = 5
arabic(11) = 4
arabic(12) = 1
roman(0) = "M"
roman(1) = "CM"
roman(2) = "D"
roman(3) = "CD"
roman(4) = "C"
roman(5) = "XC"
roman(6) = "L"
roman(7) = "XL"
roman(8) = "X"
roman(9) = "IX"
roman(10) = "V"
roman(11) = "IV"
roman(12) = "I"
Dim i As Integer, result As String
For i = 0 To 12
Do While value >= arabic(i)
result = result + roman(i)
value = value - arabic(i)
Loop
Next i
toRoman = result
End Function

View file

@ -0,0 +1,15 @@
romans = {
{1000, "M"},
{900, "CM"}, {500, "D"}, {400, "CD"}, {100, "C"},
{90, "XC"}, {50, "L"}, {40, "XL"}, {10, "X"},
{9, "IX"}, {5, "V"}, {4, "IV"}, {1, "I"} }
k = io.read() + 0
for _, v in ipairs(romans) do --note that this is -not- ipairs.
val, let = unpack(v)
while k >= val do
k = k - val
io.write(let)
end
end
print()

View file

@ -0,0 +1,15 @@
define(`roman',`ifelse(eval($1>=1000),1,`M`'roman(eval($1-1000))',
`ifelse(eval($1>=900),1,`CM`'roman(eval($1-900))',
`ifelse(eval($1>=500),1,`D`'roman(eval($1-500))',
`ifelse(eval($1>=100),1,`C`'roman(eval($1-100))',
`ifelse(eval($1>=90),1,`XC`'roman(eval($1-90))',
`ifelse(eval($1>=50),1,`L`'roman(eval($1-50))',
`ifelse(eval($1>=40),1,`XL`'roman(eval($1-40))',
`ifelse(eval($1>=10),1,`X`'roman(eval($1-10))',
`ifelse(eval($1>=9),1,`IX`'roman(eval($1-9))',
`ifelse(eval($1>=5),1,`V`'roman(eval($1-5))',
`ifelse(eval($1>=4),1,`IV`'roman(eval($1-4))',
`ifelse(eval($1>=1),1,`I`'roman(eval($1-1))'
)')')')')')')')')')')')')dnl
dnl
roman(3675)

View file

@ -0,0 +1,14 @@
TOROMAN(INPUT)
;Converts INPUT into a Roman numeral. INPUT must be an integer between 1 and 3999
;OUTPUT is the string to return
;I is a loop variable
;CURRVAL is the current value in the loop
QUIT:($FIND(INPUT,".")>1)!(INPUT<=0)!(INPUT>3999) "Invalid input"
NEW OUTPUT,I,CURRVAL
SET OUTPUT="",CURRVAL=INPUT
SET:$DATA(ROMANNUM)=0 ROMANNUM="I^IV^V^IX^X^XL^L^XC^C^CD^D^CM^M"
SET:$DATA(ROMANVAL)=0 ROMANVAL="1^4^5^9^10^40^50^90^100^400^500^900^1000"
FOR I=$LENGTH(ROMANVAL,"^"):-1:1 DO
.FOR Q:CURRVAL<$PIECE(ROMANVAL,"^",I) SET OUTPUT=OUTPUT_$PIECE(ROMANNUM,"^",I),CURRVAL=CURRVAL-$PIECE(ROMANVAL,"^",I)
KILL I,CURRVAL
QUIT OUTPUT

View file

@ -0,0 +1,10 @@
RomanForm[i_Integer?Positive] :=
Module[{num = i, string = "", value, letters, digits},
digits = {{1000, "M"}, {900, "CM"}, {500, "D"}, {400, "CD"}, {100,
"C"}, {90, "XC"}, {50, "L"}, {40, "XL"}, {10, "X"}, {9,
"IX"}, {5, "V"}, {4, "IV"}, {1, "I"}};
While[num > 0, {value, letters} =
Which @@ Flatten[{num >= #[[1]], ##} & /@ digits, 1];
num -= value;
string = string <> letters;];
string]

View file

@ -0,0 +1,5 @@
RomanForm[4]
RomanForm[99]
RomanForm[1337]
RomanForm[1666]
RomanForm[6889]

View file

@ -0,0 +1,5 @@
IV
XCIX
MCCCXXXVII
MDCLXVI
MMMMMMDCCCLXXXIX

View file

@ -0,0 +1,52 @@
:- module roman.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
:- implementation.
:- import_module char, int, list, string.
main(!IO) :-
command_line_arguments(Args, !IO),
filter(is_all_digits, Args, CleanArgs),
foldl((pred(Arg::in, !.IO::di, !:IO::uo) is det :-
( Roman = to_roman(Arg) ->
format("%s => %s", [s(Arg), s(Roman)], !IO), nl(!IO)
; format("%s cannot be converted.", [s(Arg)], !IO), nl(!IO) )
), CleanArgs, !IO).
:- func to_roman(string::in) = (string::out) is semidet.
to_roman(Number) = from_char_list(build_roman(reverse(to_char_list(Number)))).
:- func build_roman(list(char)) = list(char).
:- mode build_roman(in) = out is semidet.
build_roman([]) = [].
build_roman([D|R]) = Roman :-
map(promote, build_roman(R), Interim),
Roman = Interim ++ digit_to_roman(D).
:- func digit_to_roman(char) = list(char).
:- mode digit_to_roman(in) = out is semidet.
digit_to_roman('0') = [].
digit_to_roman('1') = ['I'].
digit_to_roman('2') = ['I','I'].
digit_to_roman('3') = ['I','I','I'].
digit_to_roman('4') = ['I','V'].
digit_to_roman('5') = ['V'].
digit_to_roman('6') = ['V','I'].
digit_to_roman('7') = ['V','I','I'].
digit_to_roman('8') = ['V','I','I','I'].
digit_to_roman('9') = ['I','X'].
:- pred promote(char::in, char::out) is semidet.
promote('I', 'X').
promote('V', 'L').
promote('X', 'C').
promote('L', 'D').
promote('C', 'M').
:- end_module roman.

View file

@ -0,0 +1,48 @@
:- module roman2.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
:- implementation.
:- import_module char, int, list, string.
main(!IO) :-
command_line_arguments(Args, !IO),
filter_map(to_int, Args, CleanArgs),
foldl((pred(Arg::in, !.IO::di, !:IO::uo) is det :-
( Roman = to_roman(Arg) ->
format("%i => %s",
[i(Arg), s(from_char_list(Roman))], !IO),
nl(!IO)
; format("%i cannot be converted.", [i(Arg)], !IO), nl(!IO) )
), CleanArgs, !IO).
:- func to_roman(int) = list(char).
:- mode to_roman(in) = out is semidet.
to_roman(N) = ( N >= 1000 ->
['M'] ++ to_roman(N - 1000)
;( N >= 100 ->
digit(N / 100, 'C', 'D', 'M') ++ to_roman(N rem 100)
;( N >= 10 ->
digit(N / 10, 'X', 'L', 'C') ++ to_roman(N rem 10)
;( N >= 1 ->
digit(N, 'I', 'V', 'X')
; [] ) ) ) ).
:- func digit(int, char, char, char) = list(char).
:- mode digit(in, in, in, in) = out is semidet.
digit(1, X, _, _) = [X].
digit(2, X, _, _) = [X, X].
digit(3, X, _, _) = [X, X, X].
digit(4, X, Y, _) = [X, Y].
digit(5, _, Y, _) = [Y].
digit(6, X, Y, _) = [Y, X].
digit(7, X, Y, _) = [Y, X, X].
digit(8, X, Y, _) = [Y, X, X, X].
digit(9, X, _, Z) = [X, Z].
:- end_module roman2.

View file

@ -0,0 +1,23 @@
let digit x y z = function
1 -> [x]
| 2 -> [x;x]
| 3 -> [x;x;x]
| 4 -> [x;y]
| 5 -> [y]
| 6 -> [y;x]
| 7 -> [y;x;x]
| 8 -> [y;x;x;x]
| 9 -> [x;z]
let rec to_roman x =
if x = 0 then []
else if x < 0 then
invalid_arg "Negative roman numeral"
else if x >= 1000 then
'M' :: to_roman (x - 1000)
else if x >= 100 then
digit 'C' 'D' 'M' (x / 100) @ to_roman (x mod 100)
else if x >= 10 then
digit 'X' 'L' 'C' (x / 10) @ to_roman (x mod 10)
else
digit 'I' 'V' 'X' x

View file

@ -0,0 +1,32 @@
bundle Default {
class Roman {
nums: static : Int[];
rum : static : String[];
function : Init() ~ Nil {
nums := [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
rum := ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"];
}
function : native : ToRoman(number : Int) ~ String {
result := "";
for(i :=0; i < nums->Size(); i += 1;) {
while(number >= nums[i]) {
result->Append(rum[i]);
number -= nums[i];
};
};
return result;
}
function : Main(args : String[]) ~ Nil {
Init();
ToRoman(1999)->PrintLine();
ToRoman(25)->PrintLine();
ToRoman(944)->PrintLine();
}
}
}

View file

@ -0,0 +1,36 @@
FUNCTION encodeRoman RETURNS CHAR (
i_i AS INT
):
DEF VAR cresult AS CHAR.
DEF VAR croman AS CHAR EXTENT 7 INIT [ "M", "D", "C", "L", "X", "V", "I" ].
DEF VAR idecimal AS INT EXTENT 7 INIT [ 1000, 500, 100, 50, 10, 5, 1 ].
DEF VAR ipos AS INT INIT 1.
DO WHILE i_i > 0:
IF i_i - idecimal[ ipos ] >= 0 THEN
ASSIGN
cresult = cresult + croman[ ipos ]
i_i = i_i - idecimal[ ipos ]
.
ELSE IF ipos < EXTENT( croman ) - 1 AND i_i - ( idecimal[ ipos ] - idecimal[ ipos + 2 ] ) >= 0 THEN
ASSIGN
cresult = cresult + croman[ ipos + 2 ] + croman[ ipos ]
i_i = i_i - ( idecimal[ ipos ] - idecimal[ ipos + 2 ] )
ipos = ipos + 1
.
ELSE
ipos = ipos + 1.
END.
RETURN cresult.
END FUNCTION. /* encodeRoman */
MESSAGE
1990 encodeRoman( 1990 ) SKIP
2008 encodeRoman( 2008 ) SKIP
2000 encodeRoman( 2000 ) SKIP
1666 encodeRoman( 1666 ) SKIP
VIEW-AS ALERT-BOX.

View file

@ -0,0 +1,17 @@
declare
fun {Digit X Y Z K}
unit([X] [X X] [X X X] [X Y] [Y] [Y X] [Y X X] [Y X X X] [X Z])
.K
end
fun {ToRoman X}
if X == 0 then ""
elseif X < 0 then raise toRoman(negativeInput X) end
elseif X >= 1000 then "M"#{ToRoman X-1000}
elseif X >= 100 then {Digit &C &D &M X div 100}#{ToRoman X mod 100}
elseif X >= 10 then {Digit &X &L &C X div 10}#{ToRoman X mod 10}
else {Digit &I &V &X X}
end
end
in
{ForAll {Map [1999 25 944] ToRoman} System.showInfo}

View file

@ -0,0 +1,55 @@
oldRoman(n)={
while(n>999999,
n-=1000000;
print1("((((I))))")
);
if(n>499999,
n-=500000;
print1("I))))")
);
while(n>99999,
n-=100000;
print1("(((I)))")
);
if(n>49999,
n-=50000;
print1("I)))")
);
while(n>9999,
n-=10000;
print1("((I))")
);
if(n>4999,
n-=5000;
print1("I))")
);
while(n>999,
n-=1000;
print1("(I)")
);
if(n>499,
n-=500;
print1("I)")
);
while(n>99,
n-=100;
print1("C")
);
if(n>49,
n-=50;
print1("L");
);
while(n>9,
n-=10;
print1("X")
);
if(n>4,
n-=5;
print1("V");
);
while(n,
n--;
print1("I")
);
print()
};

View file

@ -0,0 +1,55 @@
medievalRoman(n)={
while(n>999,
n-=1000;
print1("M")
);
if(n>899,
n-=900;
print1("CM")
);
if(n>499,
n-=500;
print1("D")
);
if(n>399,
n-=400;
print1("CD")
);
while(n>99,
n-=100;
print1("C")
);
if(n>89,
n-=90;
print1("XC")
);
if(n>49,
n-=50;
print1("L")
);
if(n>39,
n-=40;
print1("XL")
);
while(n>9,
n-=10;
print1("X")
);
if(n>8,
n-=9;
print1("IX")
);
if(n>4,
n-=5;
print1("V")
);
if(n>3,
n-=4;
print1("IV")
);
while(n,
n--;
print1("I")
);
print()
};

View file

@ -0,0 +1,60 @@
/**
* int2roman
* Convert any positive value of a 32-bit signed integer to its modern roman
* numeral representation. Numerals within parentheses are multiplied by
* 1000. ie. M == 1 000, (M) == 1 000 000, ((M)) == 1 000 000 000
*
* @param number - an integer between 1 and 2147483647
* @return roman numeral representation of number
*/
function int2roman($number)
{
if (!is_int($number) || $number < 1) return false; // ignore negative numbers and zero
$integers = array(900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1);
$numerals = array('CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I');
$major = intval($number / 1000) * 1000;
$minor = $number - $major;
$numeral = $leastSig = '';
for ($i = 0; $i < sizeof($integers); $i++) {
while ($minor >= $integers[$i]) {
$leastSig .= $numerals[$i];
$minor -= $integers[$i];
}
}
if ($number >= 1000 && $number < 40000) {
if ($major >= 10000) {
$numeral .= '(';
while ($major >= 10000) {
$numeral .= 'X';
$major -= 10000;
}
$numeral .= ')';
}
if ($major == 9000) {
$numeral .= 'M(X)';
return $numeral . $leastSig;
}
if ($major == 4000) {
$numeral .= 'M(V)';
return $numeral . $leastSig;
}
if ($major >= 5000) {
$numeral .= '(V)';
$major -= 5000;
}
while ($major >= 1000) {
$numeral .= 'M';
$major -= 1000;
}
}
if ($number >= 40000) {
$major = $major/1000;
$numeral .= '(' . int2roman($major) . ')';
}
return $numeral . $leastSig;
}

View file

@ -0,0 +1,19 @@
/* From Wiki Fortran */
roman: procedure (n) returns(character (32) varying);
declare n fixed binary nonassignable;
declare (d, m) fixed binary;
declare (r, m_div) character (32) varying;
declare d_dec(13) fixed binary static initial
(1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1);
declare d_rom(13) character (2) varying static initial
('M', 'CM', 'D', 'CD', 'C', 'XC', 'L',
'XL', 'X', 'IX', 'V', 'IV', 'I');
r = '';
m = n;
do d = 1 to 13;
m_div = m / d_dec (d);
r = r || copy (d_rom (d), m_div);
m = m - d_dec (d) * m_div;
end;
return (r);
end roman;

View file

@ -0,0 +1,24 @@
/*****************************************************************
* $Author: Atanas Kebedjiev $
*****************************************************************
* Encoding an Arabic numeral to a Roman in the range 1..3999 is much simpler as Oracle provides the conversion formats.
* Please see also the SQL solution for the same task.
*/
DECLARE
FUNCTION rencode(an IN NUMBER) RETURN VARCHAR2 IS
rs VARCHAR2(20);
BEGIN
SELECT to_char(to_char(to_date(an,'YYYY'), 'RRRR'), 'RN') INTO rs FROM dual;
RETURN rs;
END;
BEGIN
DBMS_OUTPUT.PUT_LINE ('2012 = ' || rencode('2012')); -- MMXII
DBMS_OUTPUT.PUT_LINE ('1951 = ' || rencode('1951')); -- MCMLI
DBMS_OUTPUT.PUT_LINE ('1987 = ' || rencode('1987')); -- MCMLXXXVII
DBMS_OUTPUT.PUT_LINE ('1666 = ' || rencode('1666')); -- MDCLXVI
DBMS_OUTPUT.PUT_LINE ('1999 = ' || rencode('1999')); -- MCMXCIX
END;

View file

@ -0,0 +1,16 @@
my %symbols =
1 => "I", 5 => "V", 10 => "X", 50 => "L", 100 => "C",
500 => "D", 1_000 => "M";
my @subtractors =
1_000, 100, 500, 100, 100, 10, 50, 10, 10, 1, 5, 1, 1, 0;
multi sub roman (0) { '' }
multi sub roman (Int $n) {
for @subtractors -> $cut, $minus {
$n >= $cut
and return %symbols{$cut} ~ roman($n - $cut);
$n >= $cut - $minus
and return %symbols{$minus} ~ roman($n + $minus);
}
}

View file

@ -0,0 +1,3 @@
for 1 .. 2_010 -> $x {
say roman($x);
}

View file

@ -0,0 +1,3 @@
per quisque in I tum C conscribementum sic
hoc tum duos multiplicamentum comementum egresso scribe.
cis

View file

@ -0,0 +1,25 @@
use v5.12;
use Sub::SmartMatch;
use SmartMatch::Sugar qw(any);
use List::MoreUtils qw( natatime );
my %symbols = (
1 => "I", 5 => "V", 10 => "X", 50 => "L", 100 => "C",
500 => "D", 1_000 => "M"
);
my @subtractors = (
1_000, 100, 500, 100, 100, 10, 50, 10, 10, 1, 5, 1, 1, 0
);
multi roman => [0], sub { '' };
multi roman => any, sub {
my $n = shift;
my $iter = natatime 2, @subtractors;
while( my ($cut, $minus) = $iter->() ) {
$n >= $cut
and return $symbols{$cut} . roman($n - $cut);
$n >= $cut - $minus
and return $symbols{$minus} . roman($n + $minus);
}
};

View file

@ -0,0 +1 @@
say roman($_) for 1..2_012;

View file

@ -0,0 +1,10 @@
(de roman (N)
(pack
(make
(mapc
'((C D)
(while (>= N D)
(dec 'N D)
(link C) ) )
'(M CM D CD C XC L XL X IX V IV I)
(1000 900 500 400 100 90 50 40 10 9 5 4 1) ) ) ) )

View file

@ -0,0 +1,6 @@
import String;
int main(){
write(int2roman(2009) + "\n");
write(int2roman(1666) + "\n");
write(int2roman(1337) + "\n");
}

View file

@ -0,0 +1,24 @@
FUNCTION toRoman(value AS INTEGER) AS STRING
DIM arabic(0 TO 12) AS INTEGER
DIM roman(0 TO 12) AS STRING
ARRAY ASSIGN arabic() = 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1
ARRAY ASSIGN roman() = "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"
DIM i AS INTEGER
DIM result AS STRING
FOR i = 0 TO 12
DO WHILE value >= arabic(i)
result = result & roman(i)
value = value - arabic(i)
LOOP
NEXT i
toRoman = result
END FUNCTION
FUNCTION PBMAIN
'Testing
? "2009 = " & toRoman(2009)
? "1666 = " & toRoman(1666)
? "3888 = " & toRoman(3888)
END FUNCTION

View file

@ -0,0 +1,102 @@
:- use_module(library(clpfd)).
roman :-
LA = [ _ , 2010, _, 1449, _],
LR = ['MDCCLXXXIX', _ , 'CX', _, 'MDCLXVI'],
maplist(roman, LA, LR),
maplist(my_print,LA, LR).
roman(A, R) :-
A #> 0,
roman(A, [u, t, h, th], LR, []),
label([A]),
parse_Roman(CR, LR, []),
atom_chars(R, CR).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% using DCG
roman(0, []) --> [].
roman(N, [H | T]) -->
{N1 #= N / 10,
N2 #= N mod 10},
roman(N1, T),
unity(N2, H).
unity(1, u) --> ['I'].
unity(1, t) --> ['X'].
unity(1, h) --> ['C'].
unity(1, th)--> ['M'].
unity(4, u) --> ['IV'].
unity(4, t) --> ['XL'].
unity(4, h) --> ['CD'].
unity(4, th)--> ['MMMM'].
unity(5, u) --> ['V'].
unity(5, t) --> ['L'].
unity(5, h) --> ['D'].
unity(5, th)--> ['MMMMM'].
unity(9, u) --> ['IX'].
unity(9, t) --> ['XC'].
unity(9, h) --> ['CM'].
unity(9, th)--> ['MMMMMMMMM'].
unity(0, _) --> [].
unity(V, U)-->
{V #> 5,
V1 #= V - 5},
unity(5, U),
unity(V1, U).
unity(V, U) -->
{V #> 1, V #< 4,
V1 #= V-1},
unity(1, U),
unity(V1, U).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Extraction of roman "lexeme"
parse_Roman(['C','M'|T]) -->
['CM'],
parse_Roman(T).
parse_Roman(['C','D'|T]) -->
['CD'],
parse_Roman(T).
parse_Roman(['X','C'| T]) -->
['XC'],
parse_Roman(T).
parse_Roman(['X','L'| T]) -->
['XL'],
parse_Roman(T).
parse_Roman(['I','X'| T]) -->
['IX'],
parse_Roman(T).
parse_Roman(['I','V'| T]) -->
['IV'],
parse_Roman(T).
parse_Roman([H | T]) -->
[H],
parse_Roman(T).
parse_Roman([]) -->
[].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
my_print(A, R) :-
format('~w in roman is ~w~n', [A, R]).

View file

@ -0,0 +1,5 @@
<@ DEFUDOLITLIT>_RO|__Transformer|<@ DEFKEYPAR>__NationalNumericID|2</@><@ LETRESCS%NNMPAR>...|1</@></@>
<@ ENU$$DLSTLITLIT>1990,2008,1,2,64,124,1666,10001|,|
<@ SAYELTLST>...</@> is <@ SAY_ROELTLSTLIT>...|RomanLowerUnicode</@> <@ SAY_ROELTLSTLIT>...|RomanUpperUnicode</@> <@ SAY_ROELTLSTLIT>...|RomanASCII</@>
</@>

View file

@ -0,0 +1,5 @@
<# DEFINE USERDEFINEDOPCODE LITERAL LITERAL>_RO|__Transformer|<# DEFINE KEYWORD PARAMETER>__NationalNumericID|2</#><# LET RESULT CAST NATIONALNUMBER PARAMETER>...|1</#></#>
<# ENUMERATION LAMBDASPECIFIEDDELMITER LIST LITERAL LITERAL>1990,2008,1,2,64,124,1666,10001|,|
<# SAY ELEMENT LIST>...</#> is <# SAY _RO ELEMENT LIST LITERAL>...|RomanLowerUnicode</#> <# SAY _RO ELEMENT LIST LITERAL>...|RomanUpperUnicode</#> <# SAY _RO ELEMENT LIST LITERAL>...|RomanASCII</#>
</#>

View file

@ -0,0 +1,56 @@
#SymbolCount = 12 ;0 based count
DataSection
denominations:
Data.s "M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I" ;0-12
denomValues:
Data.i 1000,900,500,400,100,90,50,40,10,9,5,4,1 ;values in decending sequential order
EndDataSection
;-setup
Structure romanNumeral
symbol.s
value.i
EndStructure
Global Dim refRomanNum.romanNumeral(#SymbolCount)
Restore denominations
For i = 0 To #SymbolCount
Read.s refRomanNum(i)\symbol
Next
Restore denomValues
For i = 0 To #SymbolCount
Read refRomanNum(i)\value
Next
Procedure.s decRoman(n)
;converts a decimal number to a roman numeral
Protected roman$, i
For i = 0 To #SymbolCount
Repeat
If n >= refRomanNum(i)\value
roman$ + refRomanNum(i)\symbol
n - refRomanNum(i)\value
Else
Break
EndIf
ForEver
Next
ProcedureReturn roman$
EndProcedure
If OpenConsole()
PrintN(decRoman(1999)) ;MCMXCIX
PrintN(decRoman(1666)) ;MDCLXVI
PrintN(decRoman(25)) ;XXV
PrintN(decRoman(954)) ;CMLIV
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit")
Input()
CloseConsole()
EndIf

View file

@ -0,0 +1,24 @@
roman = "MDCLXVmdclxvi"; # UPPERCASE for thousands #
adjust_roman = "CCXXmmccxxii";
arabic = (1000000, 500000, 100000, 50000, 10000, 5000, 1000, 500, 100, 50, 10, 5, 1);
adjust_arabic = (100000, 100000, 10000, 10000, 1000, 1000, 100, 100, 10, 10, 1, 1, 0);
def arabic_to_roman(dclxvi):
org = dclxvi; # 666 #
out = "";
for scale,arabic_scale in enumerate(arabic):
if org == 0: break
multiples = org / arabic_scale;
org -= arabic_scale * multiples;
out += roman[scale] * multiples;
if org >= -adjust_arabic[scale] + arabic_scale:
org -= -adjust_arabic[scale] + arabic_scale;
out += adjust_roman[scale] + roman[scale]
return out
if __name__ == "__main__":
test = (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,25,30,40,50,60,69,70,
80,90,99,100,200,300,400,500,600,666,700,800,900,1000,1009,1444,1666,1945,1997,1999,
2000,2008,2500,3000,4000,4999,5000,6666,10000,50000,100000,500000,1000000);
for val in test:
print '%d - %s'%(val, arabic_to_roman(val))

View file

@ -0,0 +1,16 @@
romanDgts= 'ivxlcdmVXLCDM_'
def ToRoman(num):
namoR = ''
if num >=4000000:
print 'Too Big -'
return '-----'
for rdix in range(0, len(romanDgts), 2):
if num==0: break
num,r = divmod(num,10)
v,r = divmod(r, 5)
if r==4:
namoR += romanDgts[rdix+1+v] + romanDgts[rdix]
else:
namoR += r*romanDgts[rdix] + (romanDgts[rdix+1] if(v==1) else '')
return namoR[-1::-1]

View file

@ -0,0 +1,18 @@
anums = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]
rnums = "M CM D CD C XC L XL X IX V IV I".split()
def to_roman(x):
ret = []
for a,r in zip(anums, rnums):
n,x = divmod(x,a)
ret.append(r*n)
return ''.join(ret)
if __name__ == "__main__":
test = (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,25,30,40,
50,60,69,70,80,90,99,100,200,300,400,500,600,666,700,800,900,
1000,1009,1444,1666,1945,1997,1999,2000,2008,2010,2011,2500,
3000,3999)
for val in test:
print '%d - %s'%(val, to_roman(val))

View file

@ -0,0 +1 @@
as.roman(1666) # MDCLXVI

View file

@ -0,0 +1 @@
as.roman(1666) + 334 # MM

View file

@ -0,0 +1,17 @@
roman: procedure
arg number
/* handle only 1 to 3999, else return ? */
if number >= 4000 | number <= 0 then return "?"
romans = " M CM D CD C XC L XL X IX V IV I"
arabic = "1000 900 500 400 100 90 50 40 10 9 5 4 1"
result = ""
do i = 1 to words(romans)
do while number >= word(arabic,i)
result = result || word(romans,i)
number = number - word(arabic,i)
end
end
return result

View file

@ -0,0 +1,64 @@
/*REXX program converts (Arabic) decimal numbers (≥0) ──► Roman numerals*/
numeric digits 10000 /*could be higher if wanted*/
parse arg nums
if nums='' then do /*not specified? Gen some.*/
do j=0 by 11 to 111
nums=nums j
end /*j*/
nums=nums 49
do k=88 by 100 to 1200
nums=nums k
end /*k*/
nums=nums 1000 2000 3000 4000 5000 6000
do m=88 by 200 to 1200
nums=nums m
end /*m*/
nums=nums 1304 1405 1506 1607 1708 1809 1910 2011
do p=4 to 50 /*there is no limit to this*/
nums=nums 10**p
end /*p*/
end /*end generation of numbers*/
do i=1 for words(nums); x=word(nums,i)
say right(x,55) dec2rom(x)
end /*i*/
exit /*stick a fork in it, we're done.*/
/*───────────────────────────DEC2ROM subroutine─────────────────────────*/
dec2rom: procedure; parse arg n,# /*get number, assign # to a null. */
n=space(translate(n,,','),0) /*remove any commas from number. */
nulla='ZEPHIRUM NULLAE NULLA NIHIL' /*Roman words for nothing or none.*/
if n==0 then return word(nulla,1) /*return a Roman word for zero. */
maxnp=(length(n)-1)%3 /*find max(+1) # of parens to use.*/
highPos=(maxnp+1)*3 /*highest position of number. */
nn=reverse(right(n,highPos,0)) /*digits for Arabic───►Roman conv.*/
nine=9
four=4; do j=highPos to 1 by -3
_=substr(nn,j,1); select
when _==nine then hx='CM'
when _>= 5 then hx='D'copies("C",_-5)
when _==four then hx='CD'
otherwise hx=copies('C',_)
end
_=substr(nn,j-1,1); select
when _==nine then tx='XC'
when _>= 5 then tx='L'copies("X",_-5)
when _==four then tx='XL'
otherwise tx=copies('X',_)
end
_=substr(nn,j-2,1); select
when _==nine then ux='IX'
when _>= 5 then ux='V'copies("I",_-5)
when _==four then ux='IV'
otherwise ux=copies('I',_)
end
xx=hx || tx || ux
if xx\=='' then #=# ||copies('(',(j-1)%3)xx ||copies(')',(j-1)%3)
end /*j*/
if pos('(I',#)\==0 then do i=1 for 4 /*special case: M,MM,MMM,MMMM.*/
if i==4 then _ = '(IV)'
else _ = '('copies("I",i)')'
if pos(_,#)\==0 then #=changestr(_,#,copies('M',i))
end /*i*/
return #

View file

@ -0,0 +1,24 @@
: vector ( ...n"- )
here [ &, times ] dip : .data ` swap ` + ` @ ` do ` ; ;
: .I dup @ ^buffer'add ;
: .V dup 1 + @ ^buffer'add ;
: .X dup 2 + @ ^buffer'add ;
[ .I .X drop ]
[ .V .I .I .I drop ]
[ .V .I .I drop ]
[ .V .I drop ]
[ .V drop ]
[ .I .V drop ]
[ .I .I .I drop ]
[ .I .I drop ]
[ .I drop ]
&drop
10 vector .digit
: record ( an- )
10 /mod dup [ [ over 2 + ] dip record ] &drop if .digit ;
: toRoman ( n-a )
here ^buffer'set
dup 1 3999 within 0 =
[ "EX LIMITO!\n" ] [ "IVXLCDM" swap record here ] if ;

View file

@ -0,0 +1,10 @@
Symbols = { 1=>'I', 5=>'V', 10=>'X', 50=>'L', 100=>'C', 500=>'D', 1000=>'M' }
Subtractors = [ [1000, 100], [500, 100], [100, 10], [50, 10], [10, 1], [5, 1], [1, 0] ]
def roman(num)
return Symbols[num] if Symbols.has_key?(num)
Subtractors.each do |cutPoint, subtractor|
return roman(cutPoint) + roman(num - cutPoint) if num > cutPoint
return roman(subtractor) + roman(num + subtractor) if num >= cutPoint - subtractor and num < cutPoint
end
end

View file

@ -0,0 +1,20 @@
[loop]
input "Input value:";val$
print roman$(val$)
goto [loop]
' ------------------------------
' Roman numerals
' ------------------------------
FUNCTION roman$(val$)
a2r$ = "M:1000,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1"
v = val(val$)
for i = 1 to 13
r$ = word$(a2r$,i,",")
a = val(word$(r$,2,":"))
while v >= a
roman$ = roman$ + word$(r$,1,":")
v = v - a
wend
next i
END FUNCTION

View file

@ -0,0 +1,31 @@
* ROMAN(N) - Convert integer N to Roman numeral form.
*
* N must be positive and less than 4000.
*
* An asterisk appears in the result if N >= 4000.
*
* The function fails if N is not an integer.
DEFINE('ROMAN(N)UNITS') :(ROMAN_END)
* Get rightmost digit to UNITS and remove it from N.
* Return null result if argument is null.
ROMAN N RPOS(1) LEN(1) . UNITS = :F(RETURN)
* Search for digit, replace with its Roman form.
* Return failing if not a digit.
'0,1I,2II,3III,4IV,5V,6VI,7VII,8VIII,9IX,' UNITS
+ BREAK(',') . UNITS :F(FRETURN)
* Convert rest of N and multiply by 10. Propagate a
* failure return from recursive call back to caller.
ROMAN = REPLACE(ROMAN(N), 'IVXLCDM', 'XLCDM**')
+ UNITS :S(RETURN) F(FRETURN)
ROMAN_END
* Testing
OUTPUT = "1999 = " ROMAN(1999)
OUTPUT = " 24 = " ROMAN(24)
OUTPUT = " 944 = " ROMAN(944)
END

View file

@ -0,0 +1,29 @@
* # Arabic to Roman
define('roman(n)s,ch,val,str') :(roman_end)
roman roman = ge(n,4000) n :s(return)
s = 'M1000 CM900 D500 CD400 C100 XC90 L50 XL40 X10 IX9 V5 IV4 I1 '
rom1 s span(&ucase) . ch break(' ') . val span(' ') = :f(rom2)
str = str dupl(ch,(n / val))
n = remdr(n,val) :(rom1)
rom2 roman = str :(return)
roman_end
* # Roman to Arabic
define('arabic(n)s,ch,val,sum,x') :(arabic_end)
arabic s = 'M1000 D500 C100 L50 X10 V5 I1 '
n = reverse(n)
arab1 n len(1) . ch = :f(arab2)
s ch break(' ') . val
val = lt(val,x) (-1 * val)
sum = sum + val; x = val :(arab1)
arab2 arabic = sum :(return)
arabic_end
* # Test and display
tstr = '2010 1999 1492 1066 476 '
tloop tstr break(' ') . year span(' ') = :f(out)
r = roman(year)
rstr = rstr year '=' r ' '
astr = astr r '=' arabic(r) ' ' :(tloop)
out output = rstr; output = astr
end

View file

@ -0,0 +1,16 @@
--
-- This only works under Oracle and has the limitation of 1 to 3999
--- Higher numbers in the Middle Ages were represented by "superscores" on top of the numeral to multiply by 1000
--- Vertical bars to the sides multiply by 100. So |M| means 100,000
-- When the query is run, user provides the Arabic numerals for the ar_year
-- A.Kebedjiev
--
SELECT to_char(to_char(to_date(&ar_year,'YYYY'), 'RRRR'), 'RN') AS roman_year FROM DUAL;
-- or you can type in the year directly
SELECT to_char(to_char(to_date(1666,'YYYY'), 'RRRR'), 'RN') AS roman_year FROM DUAL;
ROMAN_YEAR
MDCLXVI

View file

@ -0,0 +1,13 @@
val romanDigits = Map(
1 -> "I", 5 -> "V",
10 -> "X", 50 -> "L",
100 -> "C", 500 -> "D",
1000 -> "M",
4 -> "IV", 9 -> "IX",
40 -> "XL", 90 -> "XC",
400 -> "CD", 900 -> "CM")
val romanDigitsKeys = romanDigits.keysIterator.toList sortBy (x => -x)
def toRoman(n: Int): String = romanDigitsKeys find (_ >= n) match {
case Some(key) => romanDigits(key) + toRoman(n - key)
case None => ""
}

View file

@ -0,0 +1,14 @@
def toRoman( v:Int ) : String = {
val romanNumerals = List(1000->"M",900->"CM",500->"D",400->"CD",100->"C",90->"XC",
50->"L",40->"XL",10->"X",9->"IX",5->"V",4->"IV",1->"I")
var n = v
romanNumerals.foldLeft(""){(s,t) => {val c = n/t._1; n = n-t._1*c; s + (t._2 * c) } }
}
// A small test
def test( arabic:Int ) = println( arabic + " => " + toRoman( arabic ) )
test(1990)
test(2008)
test(1666)

View file

@ -0,0 +1,2 @@
(define (to-roman n)
(format "~@r" n))

View file

@ -0,0 +1,12 @@
$ include "seed7_05.s7i";
include "stdio.s7i";
include "wrinum.s7i";
const proc: main is func
local
var integer: number is 0;
begin
for number range 1 to 3999 do
writeln(str(ROMAN, number));
end for;
end func;

View file

@ -0,0 +1 @@
2013 printRomanOn:Stdout naive:false

Some files were not shown because too many files have changed in this diff Show more