Skip to content

Instantly share code, notes, and snippets.

@chee
Last active September 15, 2018 16:34
Show Gist options
  • Select an option

  • Save chee/a35109fe33746607222dca92b4adfb5b to your computer and use it in GitHub Desktop.

Select an option

Save chee/a35109fe33746607222dca92b4adfb5b to your computer and use it in GitHub Desktop.
function deconstructor({words, number, base}) {
const which = Math.log(number) / Math.log(base) | 0
const amount = Math.pow(base, which)
const prefix = number / amount | 0
const round = amount * prefix
return {
number: prefix,
remainder: number - round,
word: words[which]
}
}
function thousands(number) {
const words = [
'',
'thousand',
'million',
'billion',
'trillion',
'quadrillion',
'quintillion',
'bazillion',
'katrillion'
]
return deconstructor({
words,
number,
base: 1000
})
}
function hundreds(number) {
const words = ['', 'hundred']
return deconstructor({
number,
words,
number,
base: 100
})
}
function teens(number) {
const words = [
'ten',
'eleven',
'twelve',
'thirteen',
'fourteen',
'fifteen',
'sixteen',
'seventeen',
'eighteen',
'nineteen'
]
const prefix = number - 10
return {
number: '',
remainder: 0,
word: words[prefix]
}
}
function tens(number) {
const words = [
'',
'ten',
'twenty',
'thirty',
'forty',
'fifty',
'sixty',
'seventy',
'eighty',
'ninety'
]
const prefix = number / 10 | 0
const round = prefix * 10
if (prefix == 1) return teens(number)
return {
number: '',
remainder: number - round,
word: words[prefix]
}
}
function ones(number) {
const words = [
'',
'one',
'two',
'three',
'four',
'five',
'six',
'seven',
'eight',
'nine'
]
return {
number: '',
remainder: 0,
word: words[number]
}
}
const functions = [{
func: thousands,
base: 1000
}, {
func: hundreds,
base: 100
}, {
func: tens,
base: 10
}, {
func: ones,
base: 1
}]
function deconstruct(number) {
return functions.reduce((current, {func, base}) => {
const numbers = [...current]
while (number > base - 1) {
const details = func(number)
numbers.push(details)
number = details.remainder
}
return numbers
}, [])
}
function reducer(previous, {number, word}) {
return `${previous ? `${previous} ` : ''}${number ? `${deconstruct(number).reduce(reducer, '')} ` : ''}${word}`.trim()
}
module.exports = number => {
let negative = false
if (number.constructor !== Number) return 'not a number'
if (!number) return 'zero'
if (number < 0) {
negative = true
number = Math.abs(number)
}
if (!Number.isFinite(number)) return negative ? 'negative infinity' : 'infinity'
const result = deconstruct(number).reduce(reducer, '').trim()
return negative ? `negative ${result}` : result
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment