Basic program to convert integer to Roman numerals?

后端 未结 24 1094
孤独总比滥情好
孤独总比滥情好 2020-11-30 11:52

I\'m trying to write a code that converts a user-inputted integer into its Roman numeral equivalent. What I have so far is:

The point of the generate_

相关标签:
24条回答
  • 2020-11-30 12:26
     """
    # This program will allow the user to input a number from 1 - 3999 (in english) and will translate it to Roman numerals.
    # sources: http://romannumerals.babuo.com/roman-numerals-100-1000
    Guys the reason why I wrote this program like that so it becomes readable for everybody. 
    Let me know if you have any questions... 
    """
    while True:
        try:
            x = input("Enter a positive integer from 1 - 3999 (without  spaces) and this program will translated to Roman numbers: ")
            inttX = int(x)
            if (inttX) == 0 or 0 > (inttX):
                print("Unfortunately, the  smallest number that you can enter is 1 ")
            elif (inttX) > 3999:
                print("Unfortunately, the  greatest number that you can enter is 3999")
            else:
                if len(x) == 1:
                    if inttX == 1:
                        first = "I"
                    elif inttX == 2:
                        first = "II"
                    elif inttX == 3:
                        first = "III"
                    elif inttX == 4:
                        first = "IV"
                    elif inttX == 5:
                        first = "V"
                    elif inttX == 6:
                        first = "VI"
                    elif inttX == 7:
                        first = "VII"
                    elif inttX == 8:
                        first = "VIII"
                    elif inttX == 9:
                        first = "IX"
                    print(first)
                    break
                if len(x) == 2:
                    a = int(x[0])
                    b = int(x[1])
                    if a == 0:
                        first = ""
                    elif a == 1:
                        first = "X"
                    elif a == 2:
                        first = "XX"
                    elif a == 3:
                        first = "XXX"
                    elif a == 4:
                        first = "XL"
                    elif a == 5:
                        first = "L"
                    elif a == 6:
                        first = "LX"
                    elif a == 7:
                        first = "LXX"
                    elif a == 8:
                        first = "LXXX"
                    elif a == 9:
                        first = "XC"
    
                    if b == 0:
                        first1 = "0"
                    if b == 1:
                        first1 = "I"
                    elif b == 2:
                        first1 = "II"
                    elif b == 3:
                        first1 = "III"
                    elif b == 4:
                        first1 = "IV"
                    elif b == 5:
                        first1 = "V"
                    elif b == 6:
                        first1 = "VI"
                    elif b == 7:
                        first1 = "VII"
                    elif b == 8:
                        first1 = "VIII"
                    elif b == 9:
                        first1 = "IX"
                    print(first + first1)
                    break
                if len(x) == 3:
                    a = int(x[0])
                    b = int(x[1])
                    c = int(x[2])
                    if a == 0:
                        first12 = ""
                    if a == 1:
                        first12 = "C"
                    elif a == 2:
                        first12 = "CC"
                    elif a == 3:
                        first12 = "CCC"
                    elif a == 4:
                        first12 = "CD"
                    elif a == 5:
                        first12 = "D"
                    elif a == 6:
                        first12 = "DC"
                    elif a == 7:
                        first12 = "DCC"
                    elif a == 8:
                        first12 = "DCCC"
                    elif a == 9:
                        first12 = "CM"
    
                    if b == 0:
                        first = ""
                    elif b == 1:
                        first = "X"
                    elif b == 2:
                        first = "XX"
                    elif b == 3:
                        first = "XXX"
                    elif b == 4:
                        first = "XL"
                    elif b == 5:
                        first = "L"
                    elif b == 6:
                        first = "LX"
                    elif b == 7:
                        first = "LXX"
                    elif b == 8:
                        first = "LXXX"
                    elif b == 9:
                        first = "XC"
    
                    if c == 1:
                        first1 = "I"
                    elif c == 2:
                        first1 = "II"
                    elif c == 3:
                        first1 = "III"
                    elif c == 4:
                        first1 = "IV"
                    elif c == 5:
                        first1 = "V"
                    elif c == 6:
                        first1 = "VI"
                    elif c == 7:
                        first1 = "VII"
                    elif c == 8:
                        first1 = "VIII"
                    elif c == 9:
                        first1 = "IX"
                    print(first12 + first + first1)
                    break
    
                if len(x) == 4:
                    a = int(x[0])
                    b = int(x[1])
                    c = int(x[2])
                    d = int(x[3])
                    if a == 0:
                        first1 = ""
                    if a == 1:
                        first1 = "M"
                    elif a == 2:
                        first1 = "MM"
                    elif a == 3:
                        first1 = "MMM"
    
                    if b == 0:
                        first12 = ""
                    if b == 1:
                        first12 = "C"
                    elif b == 2:
                        first12 = "CC"
                    elif b == 3:
                        first12 = "CCC"
                    elif b == 4:
                        first12 = "CD"
                    elif b == 5:
                        first12 = "D"
                    elif b == 6:
                        first12 = "DC"
                    elif b == 7:
                        first12 = "DCC"
                    elif b == 8:
                        first12 = "DCCC"
                    elif b == 9:
                        first12 = "CM"
    
                    if c == 0:
                        first3 = ""
                    elif c == 1:
                        first3 = "X"
                    elif c == 2:
                        first3 = "XX"
                    elif c == 3:
                        first3 = "XXX"
                    elif c == 4:
                        first3 = "XL"
                    elif c == 5:
                        first3 = "L"
                    elif c == 6:
                        first3 = "LX"
                    elif c == 7:
                        first3 = "LXX"
                    elif c == 8:
                        first3 = "LXXX"
                    elif c == 9:
                        first3 = "XC"
    
                    if d == 0:
                        first = ""
                    elif d == 1:
                        first = "I"
                    elif d == 2:
                        first = "II"
                    elif d == 3:
                        first = "III"
                    elif d == 4:
                        first = "IV"
                    elif d == 5:
                        first = "V"
                    elif d == 6:
                        first = "VI"
                    elif d == 7:
                        first = "VII"
                    elif d == 8:
                        first = "VIII"
                    elif d == 9:
                        first = "IX"
                    print(first1 + first12 + first3 + first)
                    break
        except ValueError:
            print(" Please enter a positive integer! ")
    
    0 讨论(0)
  • 2020-11-30 12:28

    This is my approach

    def itr(num):  
        dct = { 1: "I", 4: "IV", 5: "V", 9: "IX", 10: "X", 40: "XL", 50: "L", 90: "XC", 100: "C", 400: "CD", 500: "D", 900: "CM", 1000: "M" }
        if(num in dct):
            return dct[num]
    
        for i in [1000,100,10,1]:
            for j in [9*i, 5*i, 4*i, i]:
                if(num>=j):
                    return itr(j) + itr(num-j) 
    
    0 讨论(0)
  • 2020-11-30 12:29

    Here is another way, without division:

    num_map = [(1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'), (100, 'C'), (90, 'XC'),
               (50, 'L'), (40, 'XL'), (10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')]
    
    
    def num2roman(num):
    
        roman = ''
    
        while num > 0:
            for i, r in num_map:
                while num >= i:
                    roman += r
                    num -= i
    
        return roman
    
    # test 
    >>> num2roman(2242)
    'MMCCXLII'
    

    Update see the execution visualized

    0 讨论(0)
  • 2020-11-30 12:29

    Only 1 - 999

    while True:
    
     num = input()
     def val(n):
        if n == 1:
            rom = 'I'
            return rom
        if n == 4:
            rom = 'IV'
            return rom
        if n == 5:
            rom = 'V'
            return rom
        if n == 9:
            rom = 'IX'
            return rom
        if n == 10:
            rom = 'X'
            return rom
        if n == 40:
            rom = 'XL'
            return rom
        if n == 50:
            rom = 'L'
            return rom
        if n == 90:
            rom = 'XC'
            return rom
        if n == 100:
            rom = 'C'
            return rom
        if n == 400:
            rom = 'CD'
            return rom
        if n == 500:
            rom = 'D'
            return rom
        if n == 900:
            rom = 'CM'
            return rom
    
     def lastdigit(num02):
        num02 = num % 10
        num03 = num % 5
        if 9 > num02 > 5:
            return str('V' + 'I'*num03)
        elif num02 < 4:
            return str('I'*num03)
        else:
            return str(val(num02))
    
     k3 = lastdigit(num)
    
     def tensdigit(num12):
        num12 = num % 100 - num % 10
        num13 = num % 50
        if 90 > num12 > 50:
            return str('L' + 'X'*(num13/10))
        elif num12 < 40:
            return str('X'*(num13/10))
        else:
            return str(val(num12))
    
     k2 = tensdigit(num)
    
     def hundigit(num112):
        num112 = (num % 1000 - num % 100)
        num113 = num % 500
        if 900 > num112 > 500:
            return str('D' + 'C'*(num113/100))
        elif num112 < 400:
            return str('C'*(num113/100))
        else:
            return str(val(num112))
    
     k1 = hundigit(num)
    
     print '%s%s%s' %(k1,k2,k3)
    
    0 讨论(0)
  • 2020-11-30 12:29
    roman_map = [(1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'), (100, 'C'), (90, 'XC'),
    (50, 'L'), (40, 'XL'), (10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')]
    
    def IntToRoman (xn):
        x = xn
        y = 0
        Str = ""
        for i, r in roman_map:
             # take the number and divisible by the roman number from 1000 to 1.
            y = x//i    
    
            for j in range(0, y):
                # If after divisibility is not 0 then take the roman number from list into String.
                Str = Str+r 
    
            # Take the remainder to next round.
            x = x%i 
        print(Str)
        return Str
    

    Test case:

    >>> IntToRoman(3251)
    MMMCCLI
    'MMMCCLI'
    
    0 讨论(0)
  • 2020-11-30 12:34

    I have produced an answer that works for any int >= 0:

    Save the following as romanize.py

    def get_roman(input_number: int, overline_code: str = '\u0305') -> str:
        """
        Recursive function which returns roman numeral (string), given input number (int)
    
        >>> get_roman(0)
        'N'
        >>> get_roman(3999)
        'MMMCMXCIX'
        >>> get_roman(4000)
        'MV\u0305'
        >>> get_roman(4000, overline_code='^')
        'MV^'
        """
        if input_number < 0 or not isinstance(input_number, int):
            raise ValueError(f'Only integers, n, within range, n >= 0 are supported.')
        if input_number <= 1000:
            numeral, remainder = core_lookup(input_number=input_number)
        else:
            numeral, remainder = thousand_lookup(input_number=input_number, overline_code=overline_code)
        if remainder != 0:
            numeral += get_roman(input_number=remainder, overline_code=overline_code)
        return numeral
    
    
    def core_lookup(input_number: int) -> (str, int):
        """
        Returns highest roman numeral (string) which can (or a multiple thereof) be looked up from number map and the
        remainder (int).
    
        >>> core_lookup(3)
        ('III', 0)
        >>> core_lookup(999)
        ('CM', 99)
        >>> core_lookup(1000)
        ('M', 0)
        """
        if input_number < 0 or input_number > 1000 or not isinstance(input_number, int):
            raise ValueError(f'Only integers, n, within range, 0 <= n <= 1000 are supported.')
        basic_lookup = NUMBER_MAP.get(input_number)
        if basic_lookup:
            numeral = basic_lookup
            remainder = 0
        else:
            multiple = get_multiple(input_number=input_number, multiples=NUMBER_MAP.keys())
            count = input_number // multiple
            remainder = input_number % multiple
            numeral = NUMBER_MAP[multiple] * count
        return numeral, remainder
    
    
    def thousand_lookup(input_number: int, overline_code: str = '\u0305') -> (str, int):
        """
        Returns highest roman numeral possible, that is a multiple of or a thousand that of which can be looked up from
        number map and the remainder (int).
    
        >>> thousand_lookup(3000)
        ('MMM', 0)
        >>> thousand_lookup(300001, overline_code='^')
        ('C^C^C^', 1)
        >>> thousand_lookup(30000002, overline_code='^')
        ('X^^X^^X^^', 2)
        """
        if input_number <= 1000 or not isinstance(input_number, int):
            raise ValueError(f'Only integers, n, within range, n > 1000 are supported.')
        num, k, remainder = get_thousand_count(input_number=input_number)
        numeral = get_roman(input_number=num, overline_code=overline_code)
        numeral = add_overlines(base_numeral=numeral, num_overlines=k, overline_code=overline_code)
    
        # Assume:
        # 4000 -> MV^, https://en.wikipedia.org/wiki/4000_(number)
        # 6000 -> V^M, see https://en.wikipedia.org/wiki/6000_(number)
        # 9000 -> MX^, see https://en.wikipedia.org/wiki/9000_(number)
        numeral = numeral.replace(NUMBER_MAP[1] + overline_code, NUMBER_MAP[1000])
        return numeral, remainder
    
    
    def get_thousand_count(input_number: int) -> (int, int, int):
        """
        Returns three integers defining the number, number of thousands and remainder
    
        >>> get_thousand_count(999)
        (999, 0, 0)
        >>> get_thousand_count(1001)
        (1, 1, 1)
        >>> get_thousand_count(2000002)
        (2, 2, 2)
        """
        num = input_number
        k = 0
        while num >= 1000:
            k += 1
            num //= 1000
        remainder = input_number - (num * 1000 ** k)
        return num, k, remainder
    
    
    def get_multiple(input_number: int, multiples: iter) -> int:
        """
        Given an input number(int) and a list of numbers, finds the number in list closest (rounded down) to input number
    
        >>> get_multiple(45, [1, 2, 3])
        3
        >>> get_multiple(45, [1, 2, 3, 44, 45, 46])
        45
        >>> get_multiple(45, [1, 4, 5, 9, 10, 40, 50, 90])
        40
        """
        options = sorted(list(multiples) + [input_number])
        return options[options.index(input_number) - int(input_number not in multiples)]
    
    
    def add_overlines(base_numeral: str, num_overlines: int = 1, overline_code: str = '\u0305') -> str:
        """
        Adds overlines to input base numeral (string) and returns the result.
    
        >>> add_overlines(base_numeral='II', num_overlines=1, overline_code='^')
        'I^I^'
        >>> add_overlines(base_numeral='I^I^', num_overlines=1, overline_code='^')
        'I^^I^^'
        >>> add_overlines(base_numeral='II', num_overlines=2, overline_code='^')
        'I^^I^^'
        """
        return ''.join([char + overline_code*num_overlines if char.isalnum() else char for char in base_numeral])
    
    
    def gen_number_map() -> dict:
        """
        Returns base number mapping including combinations like 4 -> IV and 9 -> IX, etc.
        """
        mapping = {
            1000: 'M',
            500: 'D',
            100: 'C',
            50: 'L',
            10: 'X',
            5: 'V',
            1: 'I',
            0: 'N'
        }
        for exponent in range(3):
            for num in (4, 9,):
                power = 10 ** exponent
                mapping[num * power] = mapping[1 * power] + mapping[(num + 1) * power]
        return mapping
    
    
    NUMBER_MAP = gen_number_map()
    
    
    if __name__ == '__main__':
        import doctest
        doctest.testmod(verbose=True, raise_on_error=True)
        # Optional extra tests
        # doctest.testfile('test_romanize.txt', verbose=True)
    

    Here are some extra tests in case useful. Save the following as test_romanize.txt in the same directory as the romanize.py:

    The ``romanize`` module
    =======================
    
    
    The ``get_roman`` function
    --------------------------
    
    Import statement:
    
        >>> from romanize import get_roman
    
    Tests:
    
        >>> get_roman(0)
        'N'
        >>> get_roman(6)
        'VI'
        >>> get_roman(11)
        'XI'
        >>> get_roman(345)
        'CCCXLV'
        >>> get_roman(989)
        'CMLXXXIX'
        >>> get_roman(989000000, overline_code='^')
        'C^^M^^L^^X^^X^^X^^M^X^^'
        >>> get_roman(1000)
        'M'
        >>> get_roman(1001)
        'MI'
        >>> get_roman(2000)
        'MM'
        >>> get_roman(2001)
        'MMI'
        >>> get_roman(900)
        'CM'
        >>> get_roman(4000, overline_code='^')
        'MV^'
        >>> get_roman(6000, overline_code='^')
        'V^M'
        >>> get_roman(9000, overline_code='^')
        'MX^'
        >>> get_roman(6001, overline_code='^')
        'V^MI'
        >>> get_roman(9013, overline_code='^')
        'MX^XIII'
        >>> get_roman(70000000000, overline_code='^')
        'L^^^X^^^X^^^'
        >>> get_roman(9000013, overline_code='^')
        'M^X^^XIII'
        >>> get_roman(989888003, overline_code='^')
        'C^^M^^L^^X^^X^^X^^M^X^^D^C^C^C^L^X^X^X^V^MMMIII'
    
    
    The ``get_thousand_count`` function
    --------------------------
    
    Import statement:
    
        >>> from romanize import get_thousand_count
    
    Tests:
    
        >>> get_thousand_count(13)
        (13, 0, 0)
        >>> get_thousand_count(6013)
        (6, 1, 13)
        >>> get_thousand_count(60013)
        (60, 1, 13)
        >>> get_thousand_count(600013)
        (600, 1, 13)
        >>> get_thousand_count(6000013)
        (6, 2, 13)
        >>> get_thousand_count(999000000000000000000000000999)
        (999, 9, 999)
        >>> get_thousand_count(2005)
        (2, 1, 5)
        >>> get_thousand_count(2147483647)
        (2, 3, 147483647)
    
    
    The ``core_lookup`` function
    --------------------------
    
    Import statement:
    
        >>> from romanize import core_lookup
    
    Tests:
    
        >>> core_lookup(2)
        ('II', 0)
        >>> core_lookup(6)
        ('V', 1)
        >>> core_lookup(7)
        ('V', 2)
        >>> core_lookup(19)
        ('X', 9)
        >>> core_lookup(900)
        ('CM', 0)
        >>> core_lookup(999)
        ('CM', 99)
        >>> core_lookup(1000)
        ('M', 0)
        >>> core_lookup(1000.2)
        Traceback (most recent call last):
        ValueError: Only integers, n, within range, 0 <= n <= 1000 are supported.
        >>> core_lookup(10001)
        Traceback (most recent call last):
        ValueError: Only integers, n, within range, 0 <= n <= 1000 are supported.
        >>> core_lookup(-1)
        Traceback (most recent call last):
        ValueError: Only integers, n, within range, 0 <= n <= 1000 are supported.
    
    
    The ``gen_number_map`` function
    --------------------------
    
    Import statement:
    
        >>> from romanize import gen_number_map
    
    Tests:
    
        >>> gen_number_map()
        {1000: 'M', 500: 'D', 100: 'C', 50: 'L', 10: 'X', 5: 'V', 1: 'I', 0: 'N', 4: 'IV', 9: 'IX', 40: 'XL', 90: 'XC', 400: 'CD', 900: 'CM'}
    
    
    The ``get_multiple`` function
    --------------------------
    
    Import statement:
    
        >>> from romanize import get_multiple
        >>> multiples = [0, 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000]
    
    Tests:
    
        >>> get_multiple(0, multiples)
        0
        >>> get_multiple(1, multiples)
        1
        >>> get_multiple(2, multiples)
        1
        >>> get_multiple(3, multiples)
        1
        >>> get_multiple(4, multiples)
        4
        >>> get_multiple(5, multiples)
        5
        >>> get_multiple(6, multiples)
        5
        >>> get_multiple(9, multiples)
        9
        >>> get_multiple(13, multiples)
        10
        >>> get_multiple(401, multiples)
        400
        >>> get_multiple(399, multiples)
        100
        >>> get_multiple(100, multiples)
        100
        >>> get_multiple(99, multiples)
        90
    
    
    The ``add_overlines`` function
    --------------------------
    
    Import statement:
    
        >>> from romanize import add_overlines
    
    Tests:
    
        >>> add_overlines('AB')
        'A\u0305B\u0305'
        >>> add_overlines('A\u0305B\u0305')
        'A\u0305\u0305B\u0305\u0305'
    
        >>> add_overlines('AB', num_overlines=3, overline_code='^')
        'A^^^B^^^'
        >>> add_overlines('A^B^', num_overlines=1, overline_code='^')
        'A^^B^^'
    
        >>> add_overlines('AB', num_overlines=3, overline_code='\u0305')
        'A\u0305\u0305\u0305B\u0305\u0305\u0305'
        >>> add_overlines('A\u0305B\u0305', num_overlines=1, overline_code='\u0305')
        'A\u0305\u0305B\u0305\u0305'
    
        >>> add_overlines('A^B', num_overlines=3, overline_code='^')
        'A^^^^B^^^'
    
        >>> add_overlines('A^B', num_overlines=0, overline_code='^')
        'A^B'
    
    0 讨论(0)
提交回复
热议问题