Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective C Number to Roman Numerals

I've been searching forever for some sample code on convert from a number to roman numerals in objective c. Anyone know where I can find a good example?

Update:

Nevermind, found a PHP function that does what I want and ported it. Seems to work fine so far.

-(NSString*)numberToRomanNumerals:(int)num{

    if (num < 0 || num > 9999) { return @""; } // out of range



    NSArray *r_ones = [[NSArray alloc]initWithObjects:@"I", @"II", @"III", @"IV", @"V", @"VI", @"VII", @"VIII",@"IX",nil];
    NSArray *r_tens = [[NSArray alloc]initWithObjects:@"X", @"XX", @"XXX", @"XL", @"L", @"LX", @"LXX",@"LXXX", @"XC",nil];
    NSArray *r_hund = [[NSArray alloc]initWithObjects:@"C", @"CC", @"CCC", @"CD", @"D", @"DC", @"DCC",@"DCCC", @"CM",nil];
    NSArray *r_thou = [[NSArray alloc]initWithObjects:@"M", @"MM", @"MMM", @"MMMM", @"MMMMM", @"MMMMMM",@"MMMMMMM",
               @"MMMMMMMM", @"MMMMMMMMM",nil];


    int ones = num % 10;
    int tens = (num - ones) % 100;
    int hundreds = (num - tens - ones) % 1000;
    int thou = (num - hundreds - tens - ones) % 10000;


    tens = tens / 10;
    hundreds = hundreds / 100;
    thou = thou / 1000;

    NSString *rnum=@"";

    if (thou) { rnum = [rnum stringByAppendingString:[r_thou objectAtIndex:thou-1]]; }
    if (hundreds) { rnum = [rnum stringByAppendingString:[r_hund objectAtIndex:hundreds-1]];    }
    if (tens) { rnum = [rnum stringByAppendingString:[r_tens objectAtIndex:tens-1]]; }
    if (ones) { rnum = [rnum stringByAppendingString:[r_ones objectAtIndex:ones-1]]; }

    [r_ones release];
    [r_tens release];
    [r_hund release];
    [r_thou release];

    return rnum;
}
like image 986
enamrik Avatar asked May 09 '11 20:05

enamrik


People also ask

What is CC in numeral?

Therefore, CC is written in numeric form as 200. Number. Roman Numeral. 200.

What is C IV in roman numerals?

CIV Roman Numerals is 104. The Roman numerals CIV are expanded according to the place value and then converted to numeric form.


2 Answers

Just a bit shorter and optimized, based on the first algorithm

+(NSString*)romain:(int)num {
    if (num < 0 || num > 9999) { return @""; } // out of range

    NSArray *r_ones = [NSArray arrayWithObjects:@"I", @"II", @"III", @"IV", @"V", @"VI", @"VII", @"VIII", @"IX", nil];
    NSArray *r_tens = [NSArray arrayWithObjects:@"X", @"XX", @"XXX", @"XL", @"L", @"LX", @"LXX",@"LXXX", @"XC", nil];
    NSArray *r_hund = [NSArray arrayWithObjects:@"C", @"CC", @"CCC", @"CD", @"D", @"DC", @"DCC",@"DCCC", @"CM", nil];
    NSArray *r_thou = [NSArray arrayWithObjects:@"M", @"MM", @"MMM", @"MMMM", @"MMMMM", @"MMMMMM", @"MMMMMMM", @"MMMMMMMM", @"MMMMMMMMM", nil];
// real romans should have an horizontal   __           ___           _____
// bar over number to make x 1000: 4000 is IV, 16000 is XVI, 32767 is XXXMMDCCLXVII...

    int thou = num / 1000;
    int hundreds = (num -= thou*1000) / 100;
    int tens = (num -= hundreds*100) / 10;
    int ones = num % 10; // cheap %, 'cause num is < 100!

    return [NSString stringWithFormat:@"%@%@%@%@",
        thou ? [r_thou objectAtIndex:thou-1] : @"",
        hundreds ? [r_hund objectAtIndex:hundreds-1] : @"",
        tens ? [r_tens objectAtIndex:tens-1] : @"",
        ones ? [r_ones objectAtIndex:ones-1] : @""];
}
like image 161
Dugh Avatar answered Sep 30 '22 19:09

Dugh


Here is the implementation of a formatter I created. It loops through a list of the different possible numbers, so it is extremely simple to modify. Right now it only converts an integer to a string, but I will update this if I implement the opposite direction.

static unsigned majorIntValues[] = {1000,100,10,1,0};
#define numMajorIntValues (sizeof(majorIntValues) / sizeof(unsigned))
static char majorCharValues[] = {'M','C','X','I','N'};
#define numMajorCharValues (sizeof(majorCharValues) / sizeof(char))
static unsigned intValues[] = {1000,500,100,50,10,5,1};
#define numIntValues (sizeof(intValues) / sizeof(unsigned))
static char charValues[] = {'M','D','C','L','X','V','I'};
#define numCharValues (sizeof(charValues) / sizeof(char))

@implementation RomanNumeralFormatter

- (NSString *)stringForObjectValue:(id)number {
    if(![number respondsToSelector:@selector(unsignedIntegerValue)]) return @"0";
    NSUInteger value = [number unsignedIntegerValue];
    if(value == 0) return @"N";
    NSMutableString *string = [NSMutableString new];
    uint8_t i,j;
    for(i = 0, j = 0; value && i < numIntValues; ++i) {
        while(intValues[i] <= majorIntValues[j]) ++j;
        while(value >= intValues[i]) {
            [string appendFormat:@"%c",charValues[i]];
            value -= intValues[i];
        }
        if(value >= (intValues[i] - majorIntValues[j])) {
            [string appendFormat:@"%c%c",majorCharValues[j],charValues[i]];
            value -= (intValues[i] - majorIntValues[j]);
        }
    }
    return [string autorelease];
}
- (NSAttributedString *)attributedStringForObjectValue:(id)anObject withDefaultAttributes:(NSDictionary *)attributes {
    return [[[NSAttributedString alloc] initWithString:[self stringForObjectValue:anObject]
                                            attributes:attributes] autorelease];
}

- (BOOL)getObjectValue:(id *)anObject forString:(NSString *)string errorDescription:(NSString **)error {
    if(error) *error = @"Decoding roman numerals is currently unsupported";
    return NO;
}

@end
like image 39
ughoavgfhw Avatar answered Sep 30 '22 17:09

ughoavgfhw