Teaching the computers to write number names using JavaScript
Tags: javascript, numbers
Published: 2021-07-24 09:52:51

Today we will try to teach the computer to translate numbers into words

## First Step

Let's use the number-word dictionary

```javascript
const numberWords = {
  0: 'zero',
  1: 'one',
  2: 'two',
  3: 'three',
  4: 'four',
  5: 'five',
  6: 'six',
  7: 'seven',
  8: 'eight',
  9: 'nine',
  10: 'ten',
}
```
### And then?

Let's write a function that will return a value if there is one in the dictionary, and _false_ if no word for the number is given

```javascript
function getNumberWord(number) {
  if (numberWords.hasOwnProperty(number)) {
    return numberWords[number]
  } else {
    return false
  }
}
```

Let's write the code to output the results of our work

```javascript
const number = process.argv[2]
console.log(getNumberWord(number))
```

### First result

```bash
node index.js 5
five
```
**Great!**

## Moving forward

```bash
node index.js 101
false
```
**Not bad**

We learned how to convert simple numbers into words, but what if we want to work with numbers that are not in our dictionary? Possibly we could identify all the numbers in the dictionary. **But**

* This is boring
* And memory consuming

### Learning to make words

So that you don't have to spend all day compiling dictionaries and leave your computer with a little more memory for more important tasks. And it has them, believe me!

Modify our program so that it adds the result of digit translation to the resulting string

```javascript
const number = process.argv[2]

let result = ''
number.forEach((digit) => {
  result += getNumberWord(digit)
})

console.log(result)
```

```bash
node index.js 101
onezeroone
```
**Good!**

## Add power

Define a dictionary for the powers, the key of which will be the number of zeros in the number

```javascript
const numberZeros = {
  1: 'ten',
  2: 'hundred',
  3: 'thousand',
  6: 'million',
}
```

By analogy with the function of getting the number word value, let's write the function of getting the word for the power

```javascript
function getPowerWord(power) {
  if (numberZeros.hasOwnProperty(power)) {
    return numberZeros[power]
  } else {
    return false
  }
}
```

Change the program so that it adds a power of a number

```javascript
const number = process.argv[2]

let result = ''

const power = number.length - 1
const numberPowerWord = getPowerWord(power)
result += numberPowerWord + getNumberWord(number.substr(power))

console.log(result)
```

```bash
node index.js 101
hundredone
```

But the current solution has problems, firstly it stopped working with the our previous number, and secondly it knows how to work with only one power

Try this solution with a number whose power is not defined in the dictionary

```bash
node index.js 10000001
false1
```
**Any problem?**

## Putting words together

To convert the power of a number, divide the number into two by adding the name of the digit between them. Also remember to check for power numbers such as "ten" in the dictionary, and use them instead of further dividing the number

![example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yj7soafcaf1x7zalvz1y.png)

```javascript
function convertPoweredNumber(number) {
  let firstDigits = ''

  for (let i = 0; i < number.length; i++) {
    firstDigits += number[i]

    const power = number.length - firstDigits.length
    const powerWord = getPowerWord(power)

    if (powerWord) {
      const nextDigitPos = firstDigits.length
      const numberWord = getNumberWord(firstDigits[0] + Array(power).fill('0').join(''))

      return numberWord
        ? numberWord + convert(number.substr(nextDigitPos))
        : convert(firstDigits) + powerWord + convert(number.substr(nextDigitPos))
    }
  }

  return ''
}
```

In the second number we can get extra zeros in the beginning. Let's split the number 10001 without having a thousand power in the dictionary, we get 100 and 01, on the next iteration we will not find 01 in the number dictionary, and again send it for splitting for powers. As a result, instead of the correct output "one" we will get "tenone"

Moreover, the user can enter a number starting with zero himself

To avoid such situations, we will delete the leading zeros in the number

```javascript
function removeLeadingZeros(number) {
  return number.replace(/^0+/, '')
}
```

Let's return the former functionality of the program and add the ability to work with power

```javascript
function convert(number) {
  const numberWithoutZeros = removeLeadingZeros(number)
  return getNumberWord(numberWithoutZeros) || convertPoweredNumber(numberWithoutZeros)
}
```

```javascript
const number = process.argv[2]
console.log(convert(number))
```

```bash
node index.js 101
onehundredone
```

## Finish!

```bash
node index.js 1000000047
onethousandmillionfourtenseven
```

To separate words, let's add a space to the values in the dictionaries, at the same time adding the value of "forty" to the dictionary of numbers

```bash
node index.js 1000000047
one thousand million forty seven
```

**Complete code** can be found on [GitHub](https://github.com/Gerpea/Projects/tree/master/Numbers/NumberNames)