I was recently asked an interview question with regards to algorithm design. The challenge is as follows:
Given a 6 or less digits positive integer (0 - 999999 inclusive), write a function
englishify(number: int)that returns the full English equivalent of that number. Here are some samples of the structure you are expected to generate:
1 - One
222 - Two Hundred And Twenty two
1234 - One Thousand, Two Hundred and Thirty Four
31337 - Thirty One Thousand, Three Hundred And Thirty Seven
100100 - One Hundred Thousand And One Hundred
200111 - Two Hundred Thousand, One Hundred And Eleven
As you may be able to see, there is a key requirement when it comes to formatting this:
- There should be a comma, not 'And', after the thousands and before the hundreds, if both exist.
I have attempted this challenge with the code below:
def englishify(number): #Numbers 0-19 (unique numbers) OneToNine= 'One Two Three Four Five Six Seven Eight Nine'.split() TenToNineteen = 'Ten Eleven Twelve Thirteen Fourteen Fifteen Sixteen Seventeen Eighteen Nineteen'.split() ZeroToNineteen = [''] + OneToNine + TenToNineteen #Numbers >= 20 at intervals of 10 Tens = 'Twenty Thirty Forty Fifty Sixty Seventy Eighty Ninety'.split() #Additional function for ease of processing of numbers def englishifyHundreds(number): #Special case: Number = 0 if number == 0: return 'Zero' #1. Number from 1-19 if number < 20: return ZeroToNineteen[number] #2. Number from 20-99 if number >= 20 and number < 100: result = Tens[int(number/10)-2] + ' ' + ZeroToNineteen[int(number%10)] return result.rstrip() #3. Number from 100-999 if number >= 100: #Separating hundreds digit and tens digit tens = number - ((number//100)*100) #Accounting for edges = 0 (number = 100, 200, ...) if number%100 == 0: return ZeroToNineteen[int(number/100)] + ' Hundred' else: return ZeroToNineteen[int(number/100)] + ' Hundred And ' + englishifyHundreds(tens) #Actual processing of number if len(str(number)) <= 3: return englishifyHundreds(number) else: #Splitting number into 'thousands' digits and 'hundreds' digits thousands = int(str(number)[:-3]) hundreds = int(str(number)[-3:]) #Accounting for edges = 0 (thousands = 1000, 2000, ...) if thousands % 1000 == 0: return englishifyHundreds(thousands) + ' Thousand' else: #Accounting for if hundreds == 0: if hundreds == 0: return englishifyHundreds(thousands) + ' Thousand' #Accounting for cases where comma is not necessary elif hundreds % 100 == 0 or hundreds < 100: return englishifyHundreds(thousands) + ' Thousand And ' + englishifyHundreds(hundreds) #Remaining cases implementing comma else: return englishifyHundreds(thousands) + ' Thousand, ' + englishifyHundreds(hundreds)
I am currently trying to rack my brains thinking of ways to optimize this, but with my limited knowledge of recursions and algorithms this is the best I can churn out for now. Hopefully I can seek some opinions from some of the more experienced programmers around here.