Simple Machines Community Forum

Customizing SMF => Tips and Tricks => Topic started by: solitario on November 19, 2004, 01:52:19 AM

Title: Roman Numerals
Post by: solitario on November 19, 2004, 01:52:19 AM
I hope this is the right forum. I just want to thank SMF for the super cool forum by donating a script I wrote. It's kinda long, but simpler than the few I've found online. Someone may have use for it.
function Roman($arabic) {
$HowMany = 0;
$Output = '';
if ($arabic==0) {
return $arabic;
continue;
} else {
if ($arabic>999) {
$HowMany = floor($arabic / 1000);
for ($i=1; $i<=$HowMany; $i++) {$Output .= "M";}
$arabic = $arabic % 1000;
}
if ($arabic>899) {
$Output .= "CM";
$arabic -= 900;
}
if ($arabic>499) {
$Output .= "D";
$arabic -= 500;
}
if ($arabic>399) {
$Output .= "CD";
$arabic -= 400;
}
if ($arabic>99) {
$HowMany = floor($arabic / 100);
for ($i=1; $i<=$HowMany; $i++) {$Output .= "C";}
$arabic = $arabic % 100;
}
if ($arabic>89) {
$Output .= "XC";
$arabic -= 90;
}
if ($arabic>49) {
$Output .= "L";
$arabic -= 50;
}
if ($arabic>39) {
$Output .= "XL";
$arabic -= 40;
}
if ($arabic>9) {
$HowMany = floor($arabic / 10);
for ($i=1; $i<=$HowMany; $i++) {$Output .= "X";}
$arabic = $arabic % 10;
}
if ($arabic>8) {
$Output .= "IX";
$arabic -= 9;
}
if ($arabic>4) {
$Output .= "V";
$arabic -= 5;
}
if ($arabic>3) {
$Output .= "IV";
$arabic -= 4;
}
if ($arabic>0) {
for ($i=1; $i<=$arabic; $i++) {$Output .= "I";}
}
return $Output;
}
}

Place the code above in Subs.php, then call it anywhere by wrapping the following around any $variable which would normally print a number:
Roman($variable)
However, this code is no good on forums with a lot of posts. (e.g., 10,001 = MMMMMMMMMMI).
Title: Re: Roman Numerals
Post by: Anguz on November 19, 2004, 05:19:02 AM
Thank you solitario! Yes, this board is fine for such a topic. I found your idea pretty interesting, I had never thought of it. Working from your code, and some spare time, I wrote another function that I think works fine too.


function Roman($arabic)
{
if (empty($arabic))
return $arabic;

$arabic = (int) $arabic;
$roman = '';
$arr = array('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);

foreach ($arr as $a => $n)
{
if ($arabic >= $n)
{
if ($a === 'M' || $a === 'C' || $a === 'X' || $a === 'I')
{
$roman .= str_repeat($a, floor($arabic / $n));
$arabic %= $n;
continue;
}
$roman .= $a;
$arabic -= $n;
}
}

return $roman;
}
Title: Re: Roman Numerals
Post by: [Unknown] on November 20, 2004, 04:59:39 AM
I might suggest... minor modifications, seems more readable imho...


function number_to_roman($arabic)
{
$arabic = (int) $arabic;

if (empty($arabic))
return $arabic;

$arr = array('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);

$roman = '';
foreach ($arr as $a => $n)
{
if ($arabic < $n)
continue;

if ($a === 'M' || $a === 'C' || $a === 'X' || $a === 'I')
{
$roman .= str_repeat($a, floor($arabic / $n));
$arabic %= $n;
continue;
}

$roman .= $a;
$arabic -= $n;
}

return $roman;
}


Would be fun on some forums, I'm sure ;).

-[Unknown]
Title: Re: Roman Numerals
Post by: Webby on November 20, 2004, 05:56:57 AM
Any samples ?
Title: Re: Roman Numerals
Post by: solitario on November 21, 2004, 03:30:44 AM
Even better, thanks!  :)
Title: Re: Roman Numerals
Post by: Zencefil on November 21, 2004, 04:29:09 AM
 
Many thanks to all of you guys! :D

Title: Re: Roman Numerals
Post by: Anguz on November 21, 2004, 04:58:33 AM
I was thinking about the first part of the function. I guess that it could be required to feed it an int, instead of casting it, since the return value will be wrong most of the time if it wasn't an int to begin with... So I suggest that if not int, return false, and then do the roman numerals conversion and return the string. For more readability, you may want to put each array element in it's own line too.


function Roman($arabic)
{
if (empty($arabic))
return;
if (!is_int($arabic))
return false;

$arr = array('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);
$roman = '';

foreach ($arr as $a => $n)
{
if ($arabic < $n)
continue;
if ($a === 'M' || $a === 'C' || $a === 'X' || $a === 'I')
{
$roman .= str_repeat($a, floor($arabic / $n));
$arabic %= $n;
continue;
}
$roman .= $a;
$arabic -= $n;
}

return $roman;
}