Just a little fun script (code block) i'd like to share for fun.
#/bin/bash
# roman.sh
#
# Function
#
num2roman() { # NUM
# Returns NUM in roman letters
#
input=$1 # input num
output="" # Clear output string
len=${#input} # Initial length to count down
roman_val() { # NUM one five ten
# This sub does the basic 'roman' algorythm
#
N=$1
one=$2
five=$3
ten=$4
out=""
case $N in
0) out+="" ;;
[123]) while [[ $N -gt 0 ]]
do out+="$one"
N=$(($N-1))
done
;;
4) out+="$one$five" ;;
5) out+="$five" ;;
[678]) out+="$five"
N=$(($N-5))
while [[ $N -gt 0 ]]
do out+="$one"
N=$(($N-1))
done
;;
9) while [[ $N -lt 10 ]]
do out+="$one"
N=$(($N+1))
done
out+="$ten"
;;
esac
echo $out
}
while [[ $len -gt 0 ]]
do # There are letters to add
num=${input:0:1}
# Do action according position
case $len in
1) # 1
output+="$(roman_val $num I V X)"
;;
2) # 10
output+="$(roman_val $num X L C)"
;;
3) # 100
output+="$(roman_val $num C D M)"
;;
*) # 1000+
# 10'000 gets a line above, 100'000 gets a line on the left.. how to?
num=${input:0:(-3)}
while [[ $num -gt 0 ]]
do output+="M"
num=$(($num-1))
done
;;
esac
input=${input:1} ; len=${#input}
done
echo $output
}
#
# Call it
#
num2roman $1
Output:
+ ~ $ for N in 1 4 5 6 8 9 10 13 42 99 123 256 1024 2048 3999;do ./roman.sh $N;done
I
IV
V
VI
VIII
IX
X
XIII
XLII
XCIX
CXXIII
CCLVI
MXXIV
MMXLVIII
MMMCMXCIX
Thank you sea for nice code , here is an awk form of same. Honestly speaking got the idea from your code and tried to make it in awk ,
lets have little more fun.
awk 'BEGIN {INPUT_NUMBERS = split("1990 2008 1666",arr," ")
for (i=1; i<=INPUT_NUMBERS; i++) {
X = arr
printf("%s = %s\n",X,ROMAN(X))
}
exit(0)
}
function ROMAN(number,Z,Y,A,B,rom1,rom10,rom100,rom1000) {
number = int(number)
if (number < 1 || number > 3999)
{
return
}
split("I II III IV V VI VII VIII IX",rom1," ")
split("X XX XXX XL L LX LXX LXXX XC",rom10," ")
split("C CC CCC CD D DC DCC DCCC CM",rom100," ")
split("M MM MMM",rom1000," ")
Z = (number - (number % 1000)) / 1000
number = number % 1000
Y = (number - (number % 100)) / 100
number = number % 100
A = (number - (number % 10)) / 10
B = number % 10
return(rom1000[Z] rom100[Y] rom10[A] rom1)
}'
Terrific...
Just one point, you are underscoring the multipy by 1000.
It should be an over bar.
Have a look at the upside down capital "C" which can be displayed as a ")" in text mode too, you might find it interesting.
I once wrote an basic article about Roman Numbers many years ago for The Crypt Magazine
The link is working and i could find most of the issues, but weren't able to locate your article as there is no directory. Would you care to tell us which issue it is in?
Cool, I did a roman -> int awk function in this thread
awk '
BEGIN {
rn="MDCLXVI" # Roman numerals desc order
split("1000 500 100 50 10 5 1",v) # value for each numeral
}
function roman_val(s,val,c,d,p,q) {
if(s !~ "^[" rn tolower(rn) "]+$") return 0;
c = split(toupper(s),d,"")
val = v[index(rn,d[c])]
while (--c) {
p = index(rn,d[c])
q = index(rn,d[c+1])
val += (p>q)? -v[p] : v[p]
}
return val
}
{ print roman_val($1) }'
True that.
But since underscore is not used by romans otherwise, and you dont mention it either in your article, and upperscore is not available in shell, and the article used underscores too.
Personaly, i find the underlined ones easier to read:
Ha ha, yeah, but it does look like an overscore and as the terminal has fixed width characters then it is easy to position underscores as overscores where you like... ;o)
@bakunin...
The URL was an AMIGA online magazine of yesteryear and I uploaded lots of kids projects and supporting code articles to it...