Search code examples
objective-cnsnumberroman-numerals

How to convert a roman numeral to an NSNumer


I am making a calculator that has a roman numeral mode. I have the operations performed in the model view, and a view controller. My problem is that I need to convert the roman numeral to a NSNumber. There is a UILabel, and the view controller takes what is in the label and sets it as the operand of the model view. Does anyone know how I can take the roman numeral from the label and make it a NSNumber? Here is some code:

- (IBAction)digitPressed:(UIButton *)sender {


    NSString *digit = [[sender titleLabel] text];
    if (self.userIsTypingNumber) {
      [self.display setText:[self.display.text stringByAppendingString:digit]];
    } else {
        [self.display setText:digit];
        self.userIsTypingNumber = YES;
    }
}

- (IBAction)operationPressed:(UIButton *)sender {

    if (self.userIsTypingNumber) {
        if ([self isValidForRoman:self.display.text] == YES) {
            //find out what roman numeral is in the display
        } else {
        NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc]init];
        [numberFormatter setNumberStyle: NSNumberFormatterDecimalStyle];
        NSNumber *n = [numberFormatter numberFromString:self.display.text];
        [[Model singleton] setOperand:n];
        self.userIsTypingNumber = NO;
        }
    }
    NSString *operation = [[sender titleLabel] text];
    NSNumber *result = [[Model singleton] performOperation:operation];
    [self.display setText:[NSString stringWithFormat:@"%@", result]];
}

- (IBAction)clearDigitPressed:(UIButton *)sender {

    [self.display setText:@""];
}

- (IBAction)clearOperationPressed:(UIButton *)sender {

    [[Model singleton] performOperation:nil];
    [self.display setText:@""];
}

- (IBAction)changeNumeralType:(id)sender {

    switch ([sender selectedSegmentIndex]) {
        case 0:
        {            
            [self.button1 setTitle:@"1" forState:UIControlStateNormal];
            [self.button2 setTitle:@"2" forState:UIControlStateNormal];
            [self.button3 setTitle:@"3" forState:UIControlStateNormal];
            [self.button4 setTitle:@"4" forState:UIControlStateNormal];
            [self.button5 setTitle:@"5" forState:UIControlStateNormal];
            [self.button6 setTitle:@"6" forState:UIControlStateNormal];
            [self.button7 setTitle:@"7" forState:UIControlStateNormal];
            [self.button8 setTitle:@"8" forState:UIControlStateNormal];
            [self.button9 setTitle:@"9" forState:UIControlStateNormal];
            [self.button0 setTitle:@"0" forState:UIControlStateNormal];
        } break;

        case 1:
        {
            [self.button1 setTitle:@"L" forState:UIControlStateNormal];
            [self.button2 setTitle:@"C" forState:UIControlStateNormal];
            [self.button3 setTitle:@"D" forState:UIControlStateNormal];
            [self.button4 setTitle:@"I" forState:UIControlStateNormal];
            [self.button5 setTitle:@"V" forState:UIControlStateNormal];
            [self.button6 setTitle:@"X" forState:UIControlStateNormal];
            [self.button7 setTitle:@"" forState:UIControlStateNormal];
            [self.button8 setTitle:@"" forState:UIControlStateNormal];
            [self.button9 setTitle:@"" forState:UIControlStateNormal];
            [self.button0 setTitle:@"M" forState:UIControlStateNormal];

        } break;

    }
}

- (BOOL)isValidForRoman:(NSString *)text
{
    NSString *romanRegex = @"^(?=.)(?i)M*(D?C{0,3}|C[DM])(L?X{0,3}|X[LC])(V?I{0,3}|I[VX])$";
    NSPredicate *romanTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", romanRegex];
    return ([romanTest evaluateWithObject:text]);
}

Solution

  • Here are a couple of resources that may help you:

    Roman Numbers Convert -This one is probably the better of the two as this has forward/backward translation

    pzearfoss / NSNumber-RomanNumerals -This is a simple category; however, it only converts NSNumber to Roman Numeral. You may be able to tweak it to go the other way around.