-1

I am trying to write a function that converts a non-negative integer to its English word representation. For example:

convertNumToEnglishLetters(123) // "One Hundred Twenty Three"
convertNumToEnglishLetters(999) // "Nine Hundred Nighty Nine"
convertNumToEnglishLetters(3333) // 'Three Thounsand Three Hundred Thirty Three'
convertNumToEnglishLetters(12312) // Twelve Thousand Three Hundred Twelve

Here is my attempt:


const ENGLISH_LETTER_BY_NUM = {
  '1' : 'One',
  '2': 'Two',
  '3': 'Three',
  //... omit some numbers for brevity
  '10': 'Ten',
  '11': 'Evelen',
  '13': 'ThirdTeen',
  '20': 'Twenty',
  '30': 'Thirty',
  //... omit some numbers for brevity
  '00': 'Hundred',
  '000': 'Thounsand'
}

function convertNumToEnglishLetters(num) {
  const numStr = num.toString()
  const englishLettersArr = []
  
  for(let i = numStr.length -1; i >= 0; i--) {
    let numChar = numStr[i]
    let englishLetter = ''
    if(i === numStr.length - 1) {
      if(numChar === '0') continue
      englishLetter = ENGLISH_LETTER_BY_NUM[numChar]
    } else if ( i === numStr.length - 2) {
      if(numChar === '0') continue
      if(numChar === '1') {
        numChar += numStr[i+1]
        englishLettersArr.pop()
      } else {
        numChar += '0'
      }
    
      englishLetter = ENGLISH_LETTER_BY_NUM[numChar]
    } else if( i === numStr.length - 3 ) {
       const HUNREND = ENGLISH_LETTER_BY_NUM['00']
       // numChar += '00'
       englishLetter = ENGLISH_LETTER_BY_NUM[numChar] + ' ' + HUNREND
    } else if( i === numStr.length - 4) {
      const THOUNSAND = ENGLISH_LETTER_BY_NUM['000']
      englishLetter = ENGLISH_LETTER_BY_NUM[numChar] + ' ' + THOUNSAND
    } else {
      const rest = numStr.slice(0, numStr.length - 3)
      englishLetter += convertNumToEnglishLetters(Number(rest))
        
    }
    englishLettersArr.push(englishLetter)
  }
  
  return englishLettersArr.reverse().join(' ')
}

I built a map ENGLISH_LETTER_BY_NUM with a minimal set of hard coded English letters. My solution works for numbers that are under 10000. But once the number goes past that, my solution wouldn't work anymore. I guess I need to recursively call the function to calculate part of the number when the length of the number is bigger than 4. But right now the solution is not working properly.

Layhout
  • 1,445
  • 1
  • 3
  • 16
Joji
  • 4,703
  • 7
  • 41
  • 86

1 Answers1

2

An algorithm challenge for you: try splitting the string into groups of at most 3 digits starting from the last digit. Convert each group into English for numbers between 0 and 999 in a separate function.

Precede each group with a multiplier word if it is not the first. For most purposed the multipliers are "thousand, million, billion, trillion" from right to left.

There are finer details to take care of, such as what to do with groups of three zeroes ('000'). I do not intend to re-write the posted code for you (it looks like homework), but you may be able to use parts of it for translating groups of three digits into English.

I suggest using arrays for multiplier words, 3 digit groups and their translation into English words, indexed in the same direction: the algorithm should be able to look up multiplier words (before or after groups) using the same index or by a simple calculation.

Depending on final design you could look up "multiplier" words that go before or after each group. If choosing "after" groups, you may want to include an empty string to follow the least significant group. Happy coding.

traktor
  • 17,588
  • 4
  • 32
  • 53