2
\$\begingroup\$

Though many have done it the other way around, I have not seen such code in many places. And, to be honest, I don't know why this cluster of if-statements, for-loops and while-loops works!

def parse_int(string):
    numbers = {'zero':0,'one':1,'two':2,'three':3,'four':4,'five':5,'six':6,'seven':7,'eight':8,'nine':9,'ten':10,'eleven':11,'twelve':12,'thirteen':13,'fourteen':14,'fifteen':15,'sixteen':16,'seventeen':17,'eighteen':18,'nineteen':19,'twenty':20,'thirty':30,'forty':40,'fifty':50,'sixty':60,'seventy':70,'eighty':80,'ninety':90,'eighty-six': 86, 'thirty-one': 31, 'forty-three': 43, 'forty-two': 42, 'fifty-eight': 58, 'sixty-seven': 67, 'thirty-two': 32, 'thirty-five': 35, 'seventy-nine': 79, 'thirty-four': 34, 'fifty-seven': 57, 'twenty-nine': 29, 'eighty-nine': 89, 'ninety-four': 94, 'seventy-eight': 78, 'ninety-one': 91, 'forty-one': 41, 'sixty-two': 62, 'twenty-eight': 28, 'eighty-eight': 88, 'seventy-seven': 77, 'forty-seven': 47, 'eighty-five': 85, 'eighty-three': 83, 'fifty-two': 52, 'eighty-two': 82, 'fifty-five': 55, 'twenty-seven': 27, 'seventy-four': 74, 'thirty-seven': 37, 'twenty-six': 26, 'sixty-six': 66, 'eighty-four': 84, 'sixty-four': 64, 'forty-eight': 48, 'fifty-four': 54, 'eighty-one': 81, 'thirty-three': 33, 'forty-four': 44, 'fifty-nine': 59, 'thirty-eight': 38, 'forty-six': 46, 'sixty-nine': 69, 'sixty-one': 61, 'sixty-three': 63, 'ninety-eight': 98, 'seventy-six': 76, 'seventy-one': 71, 'ninety-three': 93, 'fifty-three': 53, 'fifty-six': 56, 'seventy-five': 75, 'eighty-seven': 87, 'ninety-seven': 97, 'ninety-six': 96, 'ninety-nine': 99, 'twenty-one': 21, 'twenty-five': 25, 'ninety-five': 95, 'thirty-nine': 39, 'sixty-eight': 68, 'thirty-six': 36, 'twenty-four': 24, 'seventy-three': 73, 'seventy-two': 72, 'ninety-two': 92, 'twenty-three': 23, 'twenty-two': 22, 'forty-nine': 49, 'sixty-five': 65, 'fifty-one': 51, 'forty-five': 45}
    powers = {'vigintitrillion': 1000000000000000000000000000000000000000000000000000000000000000000000000, 'septillion': 1000000000000000000000000, 'nonillion': 1000000000000000000000000000000, 'tredecillion': 1000000000000000000000000000000000000000000, 'vigintiquadrillion': 1000000000000000000000000000000000000000000000000000000000000000000000000000, 'decillion': 1000000000000000000000000000000000, 'billion': 1000000000, 'duovigintillion': 1000000000000000000000000000000000000000000000000000000000000000000000, 'thousand': 1000, 'duodecillion': 1000000000000000000000000000000000000000, 'septemdecillion': 1000000000000000000000000000000000000000000000000000000, 'vigintinonillion': 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 'octillion': 1000000000000000000000000000, 'quinvigintillion': 1000000000000000000000000000000000000000000000000000000000000000000000000000000, 'octodecillion': 1000000000000000000000000000000000000000000000000000000000, 'novemdecillion': 1000000000000000000000000000000000000000000000000000000000000, 'trigintillion': 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 'quindecillion': 1000000000000000000000000000000000000000000000000, 'duotrigintillion': 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 'quattuordecillion': 1000000000000000000000000000000000000000000000, 'quadrillion': 1000000000000000, 'vigintiseptillion': 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 'vigintillion': 1000000000000000000000000000000000000000000000000000000000000000, 'untrigintillion': 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 'centillion': 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 'undecillion': 1000000000000000000000000000000000000, 'vigintunillion': 1000000000000000000000000000000000000000000000000000000000000000000, 'million': 1000000, 'septvigintillion': 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 'vigintisextillion': 1000000000000000000000000000000000000000000000000000000000000000000000000000000000, 'vigintiduoillion': 1000000000000000000000000000000000000000000000000000000000000000000000, 'sextillion': 1000000000000000000000, 'octovigintillion': 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 'nonvigintillion': 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 'sexdecillion': 1000000000000000000000000000000000000000000000000000, 'vigintoctillion': 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 'sexvigintillion': 1000000000000000000000000000000000000000000000000000000000000000000000000000000000, 'trevigintillion': 1000000000000000000000000000000000000000000000000000000000000000000000000, 'unvigintillion': 1000000000000000000000000000000000000000000000000000000000000000000, 'hundred': 100, 'quattuorvigintillion': 1000000000000000000000000000000000000000000000000000000000000000000000000000, 'quintillion': 1000000000000000000, 'googol': 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 'vigintiquintrillion': 1000000000000000000000000000000000000000000000000000000000000000000000000000000}
    
    result=0
    a=string.split(" ")
    b=[]
    
    for c in a:
        if c in numbers:
            b.append(c)
        elif c in powers:
            b[-1]+=" "+c
        elif c=="and":
            continue
        else:
            print("INVALID WORD:",c)
            return(None)
    
    for d, e in enumerate(b):
        if len(e.split(" "))==1:
            b[d]=numbers[e]
        else:
            b[d]=e.split(" ")
            b[d][0]=numbers[b[d][0]]
            f=1
            while f<len(b[d]):
                b[d][f]=powers[b[d][f]]
                f+=1
    
    if not(isinstance(b[0],int)):
           while len(b[0])>2:
               b[0][1]*=b[0][2]
               b[0].pop(2)
    
    while len(b)>0:
        if len(b)==1:
            if isinstance(b[0],int):
                result+=b[0]
                b.pop(0)
            else:
                while len(b[0])>1:
                    b[0][0]*=b[0][1]
                    b[0].pop(1)
                result+=b[0][0]
                b.pop(0)
        else:
            if isinstance(b[1],int):
                b[1]+=b[0][0]*b[0][1]
                b.pop(0)
            else:
                while len(b[1])>2:
                    b[1][1]*=b[1][2]
                    b[1].pop(2)
                
                if b[0][1]<b[1][1]:
                    b[1][0]+=b[0][0]*b[0][1]
                    b.pop(0)
                else:
                    result+=b[0][0]*b[0][1]
                    b.pop(0)
    
    return(result)
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Instead of the loooooooooooooooong series of 0s for the numbers, you can use ** to increase readability.

return None can be reduced to just return. Since the len() function will never will never return a negative value, while len(b) > 0: is the equivalent of just while len(b):

def parse_int(string):
    numbers = {'zero': 0,
               'one': 1,
               'two': 2,
               'three': 3,
               'four': 4,
               'five': 5,
               'six': 6,
               'seven': 7,
               'eight': 8,
               'nine': 9,
               'ten': 10,
               'eleven': 11,
               'twelve': 12,
               'thirteen': 13,
               'fourteen': 14,
               'fifteen': 15,
               'sixteen': 16,
               'seventeen': 17,
               'eighteen': 18,
               'nineteen': 19,
               'twenty': 20,
               'twenty-one': 21,
               'twenty-two': 22,
               'twenty-three': 23,
               'twenty-four': 24,
               'twenty-five': 25,
               'twenty-six': 26,
               'twenty-seven': 27,
               'twenty-eight': 28,
               'twenty-nine': 29,
               'thirty': 30,
               'thirty-one': 31,
               'thirty-two': 32,
               'thirty-three': 33,
               'thirty-four': 34,
               'thirty-five': 35,
               'thirty-six': 36,
               'thirty-seven': 37,
               'thirty-eight': 38,
               'thirty-nine': 39,
               'forty': 40,
               'forty-one': 41,
               'forty-two': 42,
               'forty-three': 43,
               'forty-four': 44,
               'forty-five': 45,
               'forty-six': 46,
               'forty-seven': 47,
               'forty-eight': 48,
               'forty-nine': 49,
               'fifty': 50,
               'fifty-one': 51,
               'fifty-two': 52,
               'fifty-three': 53,
               'fifty-four': 54,
               'fifty-five': 55,
               'fifty-six': 56,
               'fifty-seven': 57,
               'fifty-eight': 58,
               'fifty-nine': 59,
               'sixty': 60,
               'sixty-one': 61,
               'sixty-two': 62,
               'sixty-three': 63,
               'sixty-four': 64,
               'sixty-five': 65,
               'sixty-six': 66,
               'sixty-seven': 67,
               'sixty-eight': 68,
               'sixty-nine': 69,
               'seventy': 70,
               'seventy-one': 71,
               'seventy-two': 72,
               'seventy-three': 73,
               'seventy-four': 74,
               'seventy-five': 75,
               'seventy-six': 76,
               'seventy-seven': 77,
               'seventy-eight': 78,
               'seventy-nine': 79,
               'eighty': 80,
               'eighty-one': 81,
               'eighty-two': 82,
               'eighty-three': 83,
               'eighty-four': 84,
               'eighty-five': 85,
               'eighty-six': 86,
               'eighty-seven': 87,
               'eighty-eight': 88,
               'eighty-nine': 89,
               'ninety': 90,
               'ninety-one': 91,
               'ninety-two': 92,
               'ninety-three': 93,
               'ninety-four': 94,
               'ninety-five': 95,
               'ninety-six': 96,
               'ninety-seven': 97,
               'ninety-eight': 98,
               'ninety-nine': 99}
    powers = {'hundred': 10 ** 2,
              'thousand': 10 ** 3,
              'million': 10 ** 6,
              'billion': 10 ** 9,
              'quadrillion': 10 ** 15,
              'quintillion': 10 ** 18,
              'sextillion': 10 ** 21,
              'septillion': 10 ** 24,
              'octillion': 10 ** 27,
              'nonillion': 10 ** 30,
              'decillion': 10 ** 33,
              'undecillion': 10 ** 36,
              'duodecillion': 10 ** 39,
              'tredecillion': 10 ** 42,
              'quattuordecillion': 10 ** 45,
              'quindecillion': 10 ** 48,
              'sexdecillion': 10 ** 51,
              'septemdecillion': 10 ** 54,
              'octodecillion': 10 ** 57,
              'novemdecillion': 10 ** 60,
              'vigintillion': 10 ** 63,
              'vigintunillion': 10 ** 66,
              'unvigintillion': 10 ** 66,
              'duovigintillion': 10 ** 69,
              'vigintiduoillion': 10 ** 69,
              'vigintitrillion': 10 ** 72,
              'trevigintillion': 10 ** 72,
              'vigintiquadrillion': 10 ** 75,
              'quattuorvigintillion': 10 ** 75,
              'quinvigintillion': 10 ** 78,
              'vigintiquintrillion': 10 ** 78,
              'vigintisextillion': 10 ** 81,
              'sexvigintillion': 10 ** 81,
              'vigintiseptillion': 10 ** 84,
              'septvigintillion': 10 ** 84,
              'octovigintillion': 10 ** 87,
              'vigintoctillion': 10 ** 87,
              'vigintinonillion': 10 ** 90,
              'nonvigintillion': 10 ** 90,
              'trigintillion': 10 ** 93,
              'untrigintillion': 10 ** 96,
              'duotrigintillion': 10 ** 99,
              'googol': 10 ** 100,
              'centillion': 10 ** 303}
    
    result = 0
    a = string.split(" ")
    b = []
    
    for c in a:
        if c in numbers:
            b.append(c)
        elif c in powers:
            b[-1] += " " + c
        elif c == "and":
            continue
        else:
            print("INVALID WORD:",c)
            return

    for d, e in enumerate(b):
        if len(e.split(" ")) == 1:
            b[d] = numbers[e]
        else:
            b[d] = e.split(" ")
            b[d][0] = numbers[b[d][0]]
            f = 1
            while f < len(b[d]):
                b[d][f] = powers[b[d][f]]
                f += 1
    
    if not(isinstance(b[0], int)):
       while len(b[0]) > 2:
           b[0][1] *= b[0][2]
           b[0].pop(2)
    
    while len(b):
        if len(b) == 1:
            if isinstance(b[0], int):
                result += b[0]
                b.pop(0)
            else:
                while len(b[0]) > 1:
                    b[0][0] *= b[0][1]
                    b[0].pop(1)
                result += b[0][0]
                b.pop(0)
        else:
            if isinstance(b[1], int):
                b[1] += b[0][0] * b[0][1]
                b.pop(0)
            else:
                while len(b[1]) > 2:
                    b[1][1] *= b[1][2]
                    b[1].pop(2)
                
                if b[0][1] < b[1][1]:
                    b[1][0] += b[0][0] * b[0][1]
                    b.pop(0)
                else:
                    result += b[0][0] * b[0][1]
                    b.pop(0)
    
    return result
\$\endgroup\$
9
  • \$\begingroup\$ Instead of writing 10 ** 15 use 1e15 \$\endgroup\$
    – Ch3steR
    Dec 4, 2020 at 6:03
  • \$\begingroup\$ Thanks a lot for the neat formatting. \$\endgroup\$ Dec 4, 2020 at 17:15
  • \$\begingroup\$ @Chocolate How did measure the efficiency? I timeit'ed both give exact same results. Can you share how you benchmarked? \$\endgroup\$
    – Ch3steR
    Dec 4, 2020 at 17:32
  • \$\begingroup\$ @Chocolate Ran same code but couldn't reproduce same results(twice as fast). 10**15 is a tad faster than 1e15. But that difference doesn't even matter IMO. \$\endgroup\$
    – Ch3steR
    Dec 4, 2020 at 18:16
  • \$\begingroup\$ @Ch3steR Oh, in the world of programming, every micro second counts! \$\endgroup\$
    – Chocolate
    Dec 4, 2020 at 18:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.