2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -1,12 +1,11 @@
|
|||
{{omit from|GUISS}}
|
||||
|
||||
Create a function taking a positive integer as its parameter
|
||||
and returning a string containing the Roman Numeral representation
|
||||
of that integer.
|
||||
;Task:
|
||||
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.
|
||||
|
||||
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. <br>
|
||||
2008 is written as 2000=MM, 8=VIII; or MMVIII. <br>
|
||||
1666 uses each Roman symbol in descending order: MDCLXVI.
|
||||
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
|
||||
<br><br>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,92 @@
|
|||
-- roman :: Int -> String
|
||||
on roman(n)
|
||||
script romanDigits
|
||||
on lambda(a, lstPair)
|
||||
set n to remainder of a
|
||||
set v to item 1 of lstPair
|
||||
|
||||
if v > n then
|
||||
a
|
||||
else
|
||||
{remainder:n mod v, roman:(roman of a) & ¬
|
||||
replicate(n div v, item 2 of lstPair)}
|
||||
end if
|
||||
end lambda
|
||||
end script
|
||||
|
||||
roman of foldl(romanDigits, {remainder:n, roman:""}, ¬
|
||||
[[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"]])
|
||||
end roman
|
||||
|
||||
|
||||
-- TEST
|
||||
|
||||
on run
|
||||
map(roman, [2016, 1990, 2008, 2000, 1666])
|
||||
|
||||
--> {"MMXVI", "MCMXC", "MMVIII", "MM", "MDCLXVI"}
|
||||
end run
|
||||
|
||||
|
||||
|
||||
-- GENERIC LIBRARY FUNCTIONS
|
||||
|
||||
-- foldl :: (a -> b -> a) -> a -> [b] -> a
|
||||
on foldl(f, startValue, xs)
|
||||
tell mReturn(f)
|
||||
set v to startValue
|
||||
set lng to length of xs
|
||||
repeat with i from 1 to lng
|
||||
set v to lambda(v, item i of xs, i, xs)
|
||||
end repeat
|
||||
return v
|
||||
end tell
|
||||
end foldl
|
||||
|
||||
-- map :: (a -> b) -> [a] -> [b]
|
||||
on map(f, xs)
|
||||
tell mReturn(f)
|
||||
set lng to length of xs
|
||||
set lst to {}
|
||||
repeat with i from 1 to lng
|
||||
set end of lst to lambda(item i of xs, i, xs)
|
||||
end repeat
|
||||
return lst
|
||||
end tell
|
||||
end map
|
||||
|
||||
-- Egyptian multiplication - progressively doubling a list, appending
|
||||
-- stages of doubling to an accumulator where needed for binary
|
||||
-- assembly of a target length
|
||||
|
||||
-- replicate :: Int -> a -> [a]
|
||||
on replicate(n, a)
|
||||
if class of a is list then
|
||||
set out to {}
|
||||
else
|
||||
set out to ""
|
||||
end if
|
||||
if n < 1 then return out
|
||||
set dbl to a
|
||||
|
||||
repeat while (n > 1)
|
||||
if (n mod 2) > 0 then set out to out & dbl
|
||||
set n to (n div 2)
|
||||
set dbl to (dbl & dbl)
|
||||
end repeat
|
||||
return out & dbl
|
||||
end replicate
|
||||
|
||||
-- Lift 2nd class handler function into 1st class script wrapper
|
||||
-- mReturn :: Handler -> Script
|
||||
on mReturn(f)
|
||||
if class of f is script then
|
||||
f
|
||||
else
|
||||
script
|
||||
property lambda : f
|
||||
end script
|
||||
end if
|
||||
end mReturn
|
||||
16
Task/Roman-numerals-Encode/Ela/roman-numerals-encode.ela
Normal file
16
Task/Roman-numerals-Encode/Ela/roman-numerals-encode.ela
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
open number string math
|
||||
|
||||
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]] :
|
||||
(toInt k - 1)
|
||||
|
||||
toRoman 0 = ""
|
||||
toRoman x | x < 0 = fail "Negative roman numeral"
|
||||
| x >= 1000 = 'M' :: toRoman (x - 1000)
|
||||
| x >= 100 = let (q,r) = x `divrem` 100 in
|
||||
digit 'C' 'D' 'M' q ++ toRoman r
|
||||
| x >= 10 = let (q,r) = x `divrem` 10 in
|
||||
digit 'X' 'L' 'C' q ++ toRoman r
|
||||
| else = digit 'I' 'V' 'X' x
|
||||
|
||||
map (join "" << toRoman) [1999,25,944]
|
||||
|
|
@ -1,2 +1,15 @@
|
|||
*Main> map toRoman [1999,25,944]
|
||||
["MCMXCIX","XXV","CMXLIV"]
|
||||
import Data.List (mapAccumL)
|
||||
|
||||
roman :: Int -> String
|
||||
roman n = concatMap concat . snd $ mapAccumL tr n
|
||||
[(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")]
|
||||
where
|
||||
tr a (m, s) = (r, replicate q s)
|
||||
where
|
||||
(q, r) = quotRem a m
|
||||
|
||||
main :: IO ()
|
||||
main = mapM_ (putStrLn . roman) [1666, 1990, 2008, 2016, 2017]
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
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
|
||||
|
|
@ -1,50 +1,49 @@
|
|||
function roman(strIntegers) {
|
||||
'use strict';
|
||||
// DICTIONARY OF GLYPH:VALUE MAPPINGS
|
||||
var dctGlyphs = {
|
||||
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
|
||||
};
|
||||
|
||||
// LIST OF INTEGER STRINGS, WITH ANY SEPARATOR
|
||||
var strNums = typeof strIntegers === 'string' ? strIntegers : strIntegers.toString(),
|
||||
lstParts = strNums.split(/\d+/),
|
||||
strSeparator = lstParts.length > 1 ? lstParts[1] : '',
|
||||
lstDecimal = strSeparator ? strIntegers.split(strSeparator) : [strNums];
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
|
||||
// REWRITE OF DECIMAL INTEGER AS ROMAN
|
||||
function rewrite(strN) {
|
||||
var n = Number(strN);
|
||||
// If the Roman is a string, pass any delimiters through
|
||||
|
||||
/* Starting with the highest-valued glyph:
|
||||
take as many bites as we can with it
|
||||
(decrementing residual value with each bite,
|
||||
and appending a corresponding glyph copy to the string)
|
||||
before moving down to the next most expensive glyph */
|
||||
// (Int | String) -> String
|
||||
function romanTranscription(a) {
|
||||
if (typeof a === 'string') {
|
||||
var ps = a.split(/\d+/),
|
||||
dlm = ps.length > 1 ? ps[1] : undefined;
|
||||
|
||||
// return Object.keys(dctGlyphs).reduce(
|
||||
// OR:
|
||||
return 'M CM D CD C XC L XL X IX V IV I'.split(' ').reduce(
|
||||
function (s, k) {
|
||||
var v = dctGlyphs[k];
|
||||
return n >= v ? (n -= v, s + k) : s;
|
||||
}, ''
|
||||
)
|
||||
return (dlm ? a.split(dlm)
|
||||
.map(function (x) {
|
||||
return Number(x);
|
||||
}) : [a])
|
||||
.map(roman)
|
||||
.join(dlm);
|
||||
} else return roman(a);
|
||||
}
|
||||
|
||||
}
|
||||
// roman :: Int -> String
|
||||
function roman(n) {
|
||||
return [[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"]]
|
||||
.reduce(function (a, lstPair) {
|
||||
var m = a.remainder,
|
||||
v = lstPair[0];
|
||||
|
||||
// ALL REWRITTEN, WITH SEPARATOR RESTORED
|
||||
return lstDecimal.map(rewrite).join(strSeparator);
|
||||
}
|
||||
return (v > m ? a : {
|
||||
remainder: m % v,
|
||||
roman: a.roman + Array(
|
||||
Math.floor(m / v) + 1
|
||||
)
|
||||
.join(lstPair[1])
|
||||
});
|
||||
}, {
|
||||
remainder: n,
|
||||
roman: ''
|
||||
}).roman;
|
||||
}
|
||||
|
||||
// TEST
|
||||
|
||||
return [2016, 1990, 2008, "14.09.2015", 2000, 1666].map(
|
||||
romanTranscription);
|
||||
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,5 +1 @@
|
|||
roman(1999);
|
||||
// --> "MCMXCIX"
|
||||
|
||||
[1990, 2008, "14.09.2015", 2000, 1666].map(roman);
|
||||
// --> ["MCMXC", "MCMCVI", "XIV.IX.MCMCXV", "MCMC", "MDCLXVI"]
|
||||
["MMXVI", "MCMXC", "MMVIII", "XIV.IX.MMXV", "MM", "MDCLXVI"]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
(() => {
|
||||
'use strict';
|
||||
|
||||
// roman :: Int -> String
|
||||
const roman = n => [
|
||||
[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"]
|
||||
]
|
||||
.reduce((a, lstPair) => {
|
||||
const m = a.remainder,
|
||||
v = lstPair[0];
|
||||
return (v > m ? a : {
|
||||
remainder: m % v,
|
||||
roman: a.roman + Array(
|
||||
Math.floor(m / v) + 1
|
||||
)
|
||||
.join(lstPair[1])
|
||||
});
|
||||
}, {
|
||||
remainder: n,
|
||||
roman: ''
|
||||
})
|
||||
.roman;
|
||||
|
||||
// TEST
|
||||
|
||||
// If the input is a decimal string, pass any delimiters through
|
||||
// romanTranscription :: (Int | String) -> String
|
||||
const romanTranscription = a => {
|
||||
if (typeof a === 'string') {
|
||||
const ps = a.split(/\d+/),
|
||||
dlm = ps.length > 1 ? ps[1] : undefined;
|
||||
|
||||
return (dlm ? a.split(dlm)
|
||||
.map(Number) : [a])
|
||||
.map(roman)
|
||||
.join(dlm);
|
||||
} else return roman(a);
|
||||
}
|
||||
|
||||
// TEST
|
||||
return [2016, 1990, 2008, "14.09.2015", 2000, 1666]
|
||||
.map(romanTranscription);
|
||||
})();
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
"MMXVI",
|
||||
"MCMXC",
|
||||
"MMVIII",
|
||||
"XIV.IX.MMXV",
|
||||
"MM",
|
||||
"MDCLXVI"
|
||||
]
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
val romanNumerals = mapOf(
|
||||
1000 to "M",
|
||||
900 to "CM",
|
||||
500 to "D",
|
||||
400 to "CD",
|
||||
100 to "C",
|
||||
90 to "XC",
|
||||
50 to "L",
|
||||
40 to "XL",
|
||||
10 to "X",
|
||||
9 to "IX",
|
||||
5 to "V",
|
||||
4 to "IV",
|
||||
1 to "I"
|
||||
)
|
||||
|
||||
fun encode(number: Int): String? {
|
||||
if (number > 5000 || number < 1) {
|
||||
return null
|
||||
}
|
||||
var num = number
|
||||
val buffer = StringBuffer()
|
||||
for ((multiple, numeral) in romanNumerals) {
|
||||
while (num >= multiple) {
|
||||
num -= multiple
|
||||
buffer.append(numeral)
|
||||
}
|
||||
}
|
||||
return buffer.toString()
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
println(encode(1990))
|
||||
println(encode(1666))
|
||||
println(encode(2008))
|
||||
}
|
||||
|
|
@ -1,10 +1,5 @@
|
|||
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]
|
||||
RomanNumeral[4]
|
||||
RomanNumeral[99]
|
||||
RomanNumeral[1337]
|
||||
RomanNumeral[1666]
|
||||
RomanNumeral[6889]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
RomanForm[4]
|
||||
RomanForm[99]
|
||||
RomanForm[1337]
|
||||
RomanForm[1666]
|
||||
RomanForm[6889]
|
||||
IV
|
||||
XCIX
|
||||
MCCCXXXVII
|
||||
MDCLXVI
|
||||
MMMMMMDCCCLXXXIX
|
||||
|
|
|
|||
|
|
@ -1,5 +1,52 @@
|
|||
IV
|
||||
XCIX
|
||||
MCCCXXXVII
|
||||
MDCLXVI
|
||||
MMMMMMDCCCLXXXIX
|
||||
:- 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.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
:- module roman.
|
||||
:- module roman2.
|
||||
|
||||
:- interface.
|
||||
|
||||
|
|
@ -12,41 +12,37 @@
|
|||
|
||||
main(!IO) :-
|
||||
command_line_arguments(Args, !IO),
|
||||
filter(is_all_digits, Args, CleanArgs),
|
||||
filter_map(to_int, 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) )
|
||||
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(string::in) = (string::out) is semidet.
|
||||
to_roman(Number) = from_char_list(build_roman(reverse(to_char_list(Number)))).
|
||||
:- 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 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(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].
|
||||
|
||||
:- 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.
|
||||
:- end_module roman2.
|
||||
|
|
|
|||
|
|
@ -58,7 +58,4 @@ function ConvertTo-RomanNumeral
|
|||
|
||||
$RomanNumeral
|
||||
}
|
||||
End
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
1..50 | ForEach-Object {
|
||||
[PSCustomObject]@{
|
||||
SuperbowlNumber = $_
|
||||
SuperbowlNumeral = ConvertTo-RomanNumeral -Number $_
|
||||
}
|
||||
}
|
||||
11
Task/Roman-numerals-Encode/Python/roman-numerals-encode-4.py
Normal file
11
Task/Roman-numerals-Encode/Python/roman-numerals-encode-4.py
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
rnl = [ { '4' : 'MMMM', '3' : 'MMM', '2' : 'MM', '1' : 'M', '0' : '' }, { '9' : 'CM', '8' : 'DCCC', '7' : 'DCC',
|
||||
'6' : 'DC', '5' : 'D', '4' : 'CD', '3' : 'CCC', '2' : 'CC', '1' : 'C', '0' : '' }, { '9' : 'XC',
|
||||
'8' : 'LXXX', '7' : 'LXX', '6' : 'LX', '5' : 'L', '4' : 'XL', '3' : 'XXX', '2' : 'XX', '1' : 'X',
|
||||
'0' : '' }, { '9' : 'IX', '8' : 'VIII', '7' : 'VII', '6' : 'VI', '5' : 'V', '4' : 'IV', '3' : 'III',
|
||||
'2' : 'II', '1' : 'I', '0' : '' }]
|
||||
# Option 1
|
||||
def number2romannumeral(n):
|
||||
return ''.join([rnl[x][y] for x, y in zip(range(4), str(n).zfill(4)) if n < 5000 and n > -1])
|
||||
# Option 2
|
||||
def number2romannumeral(n):
|
||||
return reduce(lambda x, y: x + y, map(lambda x, y: rnl[x][y], range(4), str(n).zfill(4))) if -1 < n < 5000 else None
|
||||
|
|
@ -1,64 +1,53 @@
|
|||
/*REXX program converts (Arabic) decimal numbers (≥0) ──► Roman numerals*/
|
||||
numeric digits 10000 /*could be higher if wanted*/
|
||||
parse arg nums
|
||||
/*REXX program converts (Arabic) non─negative decimal integers (≥0) ───► Roman numerals.*/
|
||||
numeric digits 10000 /*decimal digs can be higher if wanted.*/
|
||||
parse arg # /*obtain optional integers from the CL.*/
|
||||
@er= "argument isn't a non-negative integer: " /*literal used when issuing error msg. */
|
||||
if #='' then /*Nothing specified? Then generate #s.*/
|
||||
do
|
||||
do j= 0 by 11 to 111; #=# j; end
|
||||
#=# 49; do k=88 by 100 to 1200; #=# k; end
|
||||
#=# 1000 2000 3000 4000 5000 6000; do m=88 by 200 to 1200; #=# m; end
|
||||
#=# 1304 1405 1506 1607 1708 1809 1910 2011; do p= 4 to 50; #=# 10**p; end
|
||||
end /*finished with generation of numbers. */
|
||||
|
||||
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 #
|
||||
do i=1 for words(#); x=word(#, i) /*convert each of the numbers───►Roman.*/
|
||||
if \datatype(x, 'W') | x<0 then say "***error***" @er x /*¬ whole #? negative?*/
|
||||
say right(x, 55) dec2rom(x)
|
||||
end /*i*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
dec2rom: procedure; parse arg n,# /*obtain the number, assign # to a null*/
|
||||
n=space(translate(n/1, , ','), 0) /*remove commas from normalized integer*/
|
||||
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 parenthesis to use.*/
|
||||
highPos=(maxnp+1)*3 /*highest position of number. */
|
||||
nn=reverse( right(n, highPos, 0) ) /*digits for Arabic──►Roman conversion.*/
|
||||
do j=highPos to 1 by -3
|
||||
_=substr(nn, j, 1); select /*════════════════════hundreds.*/
|
||||
when _==9 then hx='CM'
|
||||
when _>=5 then hx='D'copies("C", _-5)
|
||||
when _==4 then hx='CD'
|
||||
otherwise hx= copies('C', _)
|
||||
end /*select hundreds*/
|
||||
_=substr(nn, j-1, 1); select /*════════════════════════tens.*/
|
||||
when _==9 then tx='XC'
|
||||
when _>=5 then tx='L'copies("X", _-5)
|
||||
when _==4 then tx='XL'
|
||||
otherwise tx= copies('X', _)
|
||||
end /*select tens*/
|
||||
_=substr(nn, j-2, 1); select /*═══════════════════════units.*/
|
||||
when _==9 then ux='IX'
|
||||
when _>=5 then ux='V'copies("I", _-5)
|
||||
when _==4 then ux='IV'
|
||||
otherwise ux= copies('I', _)
|
||||
end /*select units*/
|
||||
$=hx || tx || ux
|
||||
if $\=='' then #=# || copies("(", (j-1)%3)$ ||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 #
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
((>= number 50) (string-append "L" (encode/roman (- number 50))))
|
||||
((>= number 40) (string-append "XL" (encode/roman (- number 40))))
|
||||
((>= number 10) (string-append "X" (encode/roman (- number 10))))
|
||||
((>= number 9) (string-append "IX" (encode/roman (- number 9))))
|
||||
((>= number 5) (string-append "V" (encode/roman (- number 5))))
|
||||
((>= number 4) (string-append "IV" (encode/roman (- number 4))))
|
||||
((>= number 1) (string-append "I" (encode/roman (- number 1))))
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
#lang racket
|
||||
(define (number->list n)
|
||||
(for/fold ([result null])
|
||||
([decimal '(1000 900 500 400 100 90 50 40 10 5 4 1)]
|
||||
[roman '(M CM D CD C XC L XL X V IV I)])
|
||||
([decimal '(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)])
|
||||
#:break (= n 0)
|
||||
(let-values ([(q r) (quotient/remainder n decimal)])
|
||||
(set! n r)
|
||||
|
|
|
|||
|
|
@ -1,16 +1,9 @@
|
|||
--
|
||||
-- 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
|
||||
SQL> select to_char(1666, 'RN') urcoman, to_char(1666, 'rn') lcroman from dual;
|
||||
|
||||
SELECT to_char(to_char(to_date(1666,'YYYY'), 'RRRR'), 'RN') AS roman_year FROM DUAL;
|
||||
|
||||
ROMAN_YEAR
|
||||
MDCLXVI
|
||||
URCOMAN LCROMAN
|
||||
--------------- ---------------
|
||||
MDCLXVI mdclxvi
|
||||
|
|
|
|||
34
Task/Roman-numerals-Encode/Scheme/roman-numerals-encode-2.ss
Normal file
34
Task/Roman-numerals-Encode/Scheme/roman-numerals-encode-2.ss
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
(define roman-decimal
|
||||
'(("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)))
|
||||
|
||||
(define (to-roman value)
|
||||
(apply string-append
|
||||
(let loop ((v value)
|
||||
(decode roman-decimal))
|
||||
(let ((r (caar decode))
|
||||
(d (cdar decode)))
|
||||
(cond
|
||||
((= v 0) '())
|
||||
((>= v d) (cons r (loop (- v d) decode)))
|
||||
(else (loop v (cdr decode))))))))
|
||||
|
||||
|
||||
(let loop ((n '(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)))
|
||||
(unless (null? n)
|
||||
(printf "~a ~a\n" (car n) (to-roman (car n)))
|
||||
(loop (cdr n))))
|
||||
Loading…
Add table
Add a link
Reference in a new issue