Integer to roman

Posted by Gatete on Aug. 4, 2016, 1:47 p.m.

So I was browsing the web for a way to convert an integer into a Roman number. Surprisingly there was not any for GML and I only found one for Javascript.

Said code can be found here.

http://stackoverflow.com/questions/9083037/convert-a-number-into-a-roman-numeral-in-javascript

After that, I tried to port it into GML which I did succesfully after a lot of errors

///integer_to_roman(string);

/*
**  Usage:
**      integer_to_roman(string);
**
**  Argument:
**      string      String to convert
**
**  Returns:
**      The string converted into roman numerals.
*/

//Temporary string
var str = "";

//Given input
input = argument[0];

//First, let's check the input.
if ((input < 1) || (input > 3999)) { //If the number is lower than 1 or greater than 3999.

    exit;
}

//Otherwise, convert the input into roman numerals.
else {

    //1000 into "M".
    while (input >= 1000) { str += "M"; input -= 1000; }

    //900 into "CM".
    while (input >= 900) { str += "CM"; input -= 900; }

    //500 into "D".
    while (input >= 500) { str += "D"; input -= 500; }

    //400 into "CD".
    while (input >= 400) { str += "CD"; input -= 400; }

    //100 into "C".
    while (input >= 100) { str += "C"; input -= 100; }

    //90 into "XC".
    while (input >= 90) { str += "XC"; input -= 90; }

    //50 into "L".
    while (input >= 50) { str += "L"; input -= 50; }

    //40 into "XL".
    while (input >= 40) { str += "XL"; input -= 40; }
    
    //10 into "X".
    while (input >= 10) { str += "X"; input -= 10; }
    
    //9 into "IX".
    while (input >= 9) { str += "IX"; input -= 9; }
    
    //5 into "V".
    while (input >= 5) { str += "V"; input -= 5; }

    //4 into "IV".
    while (input >= 4) { str += "IV"; input -= 4; }
    
    //1 into "I".
    while (input >= 1) { str += "I"; input -= 1; }
}

//Return the obtained string
return str;

Here, you can see a gif of it in action.

NOTE: This will work only with a number between 1 and 3999

Comments

Jani_Nykanen 7 years, 9 months ago

I wonder if there is a way to do that without so many while loops.

EDIT: The Javascript one did have only one while loop, but I wonder if it's possible to do without any while loops.

Nopykon 7 years, 9 months ago

Quote: Jani
The Javascript one did have only one while loop, but I wonder if it's possible to do without any while loops
For loops! 8) Or jump lables. :P

But I think it would be would be hard/silly to try and avoid _all_ loops. All itoa functions I can remember uses at least one loop, for a simpler problem.

Acid 7 years, 9 months ago

Your method makes more sense to humans, but there's also this way:

https://discuss.leetcode.com/topic/12384/simple-solution/16

Nopykon 7 years, 9 months ago

Quote: Acid
Your method makes more sense to humans, but there's also this way…
No, that makes perfect sense for humans too I think. Very sweet.

Quote: Steven
I don't understand pls explain, yes, I played gtaIV but what? EDIT: ah. pls.

Decided to write a function for C… case I'd want to use it for some reason.

C
void roman_str(
    char*str, //should be 16 in length at least
    int num//max 3999
    )
{
        static const char* rom[4][10]={
    {"","I","II","III","IV","V","VI","VII","VIII","IX"},
    {"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"},
    {"","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"},
    {"","M","MM","MMM"}
        };
        *str = '\0';//safety measure if str is not zeroed
        strcat(  str, rom[3][ num / 1000 ] );
        strcat(  str, rom[2][ num / 100 % 10 ] );
        strcat(  str, rom[1][ num / 10 % 10 ] );
        strcat(  str, rom[0][ num % 10 ] );
}

Or, without libc.

C
void roman_str(
    char*s, //should be at least 16 in length
    int num //max 3999
    )
{
        static const char rom[4][10][4]={
       {"","I","II","III","IV","V","VI","VII","VIII","IX"},
       {"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"},
       {"","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"},
       {"","M","MM","MMM"}
        };
        int i,n;
        for( *s=i=0, n = num / 1000; i < 4 && rom[3][n][i] ; *s++ = rom[3][n][i],  ++i );
        for( *s=i=0, n = num / 100 % 10 ; i < 4 && rom[2][n][i] ; *s++ = rom[2][n][i],  ++i );
        for( *s=i=0, n = num / 10 % 10 ; i < 4 && rom[1][n][i] ; *s++ = rom[1][n][i],  ++i );
        for( *s=i=0, n = num % 10 ; i < 4 && rom[0][n][i] ; *s++ = rom[0][n][i],  ++i );
        *s= 0;
}

Gatete 7 years, 9 months ago

If the input is equal to 4000 you get a IV with a _ above. But how can that be coded.