From c7ef1919d9898c829c5fb36e2eb612bdf0bde69f Mon Sep 17 00:00:00 2001 From: Ben Burwell Date: Fri, 29 Jul 2016 11:35:17 -0400 Subject: Initial commit --- .gitignore | 1 + .travis.yml | 26 +++++++++++++++++++ index.js | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/digits.js | 31 ++++++++++++++++++++++ lib/multipliers.js | 26 +++++++++++++++++++ lib/utils.js | 20 +++++++++++++++ package.json | 24 +++++++++++++++++ test/index.js | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 276 insertions(+) create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 index.js create mode 100644 lib/digits.js create mode 100644 lib/multipliers.js create mode 100644 lib/utils.js create mode 100644 package.json create mode 100644 test/index.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..76744f2 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,26 @@ +language: node_js +node_js: + - "6.1.x" + - "6.0.x" + - "5.11.x" + - "5.10.x" + - "5.9.x" + - "5.8.x" + - "5.7.x" + - "5.6.x" + - "5.5.x" + - "5.4.x" + - "5.3.x" + - "5.2.x" + - "5.1.x" + - "5.0.x" + - "4.4.x" + - "4.3.x" + - "4.2.x" + - "4.1.x" + - "4.0.x" + - "0.12.x" + - "0.11.x" + - "0.10.x" + - "0.8.x" + - "0.6.x" diff --git a/index.js b/index.js new file mode 100644 index 0000000..2b08cbe --- /dev/null +++ b/index.js @@ -0,0 +1,75 @@ +var multipliers = require('./lib/multipliers.js'); +var digits = require('./lib/digits.js'); +var utils = require('./lib/utils.js'); +var BigNum = require('bignumber.js'); + +function parseTriple(str, useAnd, hasBigger) { + var hundredsDigit = 0; + var tensDigit = 0; + var onesDigit = 0; + var bottomPair = 0; + if (str.length === 3) { + hundredsDigit = utils.atoi(str[0]); + tensDigit = utils.atoi(str[1]); + onesDigit = utils.atoi(str[2]); + bottomPair = utils.atoi(str.substring(1, 3)); + } else if (str.length === 2) { + tensDigit = utils.atoi(str[0]); + onesDigit = utils.atoi(str[1]); + bottomPair = utils.atoi(str); + } else if (str.length === 1) { + onesDigit = utils.atoi(str[0]); + bottomPair = onesDigit; + } + var parts = []; + if (hundredsDigit > 0 && digits.hasOwnProperty(hundredsDigit)) { + parts.push(digits[hundredsDigit]); + parts.push('hundred'); + } + if (hundredsDigit > 0) { + hasBigger = true; + } + if (hasBigger && bottomPair > 0 && useAnd) { + parts.push('and'); + } + if (bottomPair > 0 && digits.hasOwnProperty(bottomPair)) { + parts.push(digits[bottomPair]); + } else { + if (tensDigit > 0 && digits.hasOwnProperty(tensDigit * 10)) { + parts.push(digits[tensDigit * 10]); + } + if (onesDigit > 0 && digits.hasOwnProperty(onesDigit)) { + parts.push(digits[onesDigit]); + } + } + return parts; +}; + +function numToAlpha(input, useAnd) { + var bn = new BigNum(input).toString(10); + var parts = []; + var numString = bn; + if (bn[0] === '-') { + parts.push('negative'); + numString = bn.substring(1, bn.length); + } + if (numString === '0') { + parts.push('zero'); + } else { + var chunks = utils.chunkify(numString); + chunks.forEach(function(chunk, idx) { + var mult = chunks.length - idx - 1; + var useAndForChunk = useAnd && mult === 0; + var triple = parseTriple(chunk, useAndForChunk, chunks.length > 1); + if (triple.length > 0) { + Array.prototype.push.apply(parts, triple); + if (multipliers.hasOwnProperty(mult)) { + parts.push(multipliers[mult]); + } + } + }); + } + return parts.join(' '); +}; + +module.exports = numToAlpha; diff --git a/lib/digits.js b/lib/digits.js new file mode 100644 index 0000000..7268b62 --- /dev/null +++ b/lib/digits.js @@ -0,0 +1,31 @@ +var digitToAlpha = { + 1: 'one', + 2: 'two', + 3: 'three', + 4: 'four', + 5: 'five', + 6: 'six', + 7: 'seven', + 8: 'eight', + 9: 'nine', + 10: 'ten', + 11: 'eleven', + 12: 'twelve', + 13: 'thirteen', + 14: 'fourteen', + 15: 'fifteen', + 16: 'sixteen', + 17: 'seventeen', + 18: 'eighteen', + 19: 'nineteen', + 20: 'twenty', + 30: 'thirty', + 40: 'forty', + 50: 'fifty', + 60: 'sixty', + 70: 'seventy', + 80: 'eighty', + 90: 'ninety', +}; + +module.exports = digitToAlpha; diff --git a/lib/multipliers.js b/lib/multipliers.js new file mode 100644 index 0000000..77194e1 --- /dev/null +++ b/lib/multipliers.js @@ -0,0 +1,26 @@ +var multiplierToAlpha = { + 1: 'thousand', + 2: 'million', + 3: 'billion', + 4: 'trillion', + 5: 'quadrillion', + 6: 'quintillion', + 7: 'sextillion', + 8: 'septillion', + 9: 'octillion', + 10: 'nonillion', + 11: 'decillion', + 12: 'undecillion', + 13: 'duodecillion', + 14: 'tredecillion', + 15: 'quattuordecillion', + 16: 'quindecillion', + 17: 'sexdecillion', + 18: 'septendecillion', + 19: 'octodecillion', + 20: 'novemdecillion', + 21: 'vigintillion', + 22: 'centillion', +}; + +module.exports = multiplierToAlpha; diff --git a/lib/utils.js b/lib/utils.js new file mode 100644 index 0000000..2c3ce8b --- /dev/null +++ b/lib/utils.js @@ -0,0 +1,20 @@ +function atoi(str) { + return parseInt(str, 10); +}; + +function chunkify(str) { + var parts = []; + var offset = 0; + var length = str.length % 3 || 3; + while (offset < str.length) { + parts.push(str.substring(offset, offset + length)); + offset += length; + length = 3; + } + return parts; +} + +module.exports = { + atoi: atoi, + chunkify: chunkify, +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..19c4344 --- /dev/null +++ b/package.json @@ -0,0 +1,24 @@ +{ + "name": "itoa", + "version": "1.0.0", + "description": "Convert 10 to ten, all the way up to one centillion!", + "main": "index.js", + "scripts": { + "test": "mocha test/index.js" + }, + "keywords": [ + "number", + "number", + "names", + "math" + ], + "author": "Ben Burwell", + "license": "MIT", + "devDependencies": { + "mocha": "^2.5.3", + "should": "^10.0.0" + }, + "dependencies": { + "bignumber.js": "^2.4.0" + } +} diff --git a/test/index.js b/test/index.js new file mode 100644 index 0000000..6bbb0bf --- /dev/null +++ b/test/index.js @@ -0,0 +1,73 @@ +var should = require('should'); +var itoa = require('../'); + +describe('itoa', function() { + describe('input types', function() { + it('should handle string inputs', function() { + itoa('12').should.equal('twelve'); + }); + it('should handle number inputs', function() { + itoa(12).should.equal('twelve'); + }); + it('should handle hex inputs (using bignumber.js)', function() { + itoa('0x10').should.equal('sixteen'); + }); + }); + + describe('special cases', function() { + it('should handle zero', function() { + itoa('0').should.equal('zero'); + }); + it('should handle negatives', function() { + itoa('-27').should.equal('negative twenty seven'); + }); + }); + + describe('triples', function() { + it('should handle one-digit numbers', function() { + itoa('6').should.equal('six'); + }); + it('should handle two-digit numbers like nineteen', function() { + itoa('19').should.equal('nineteen'); + }); + it('should handle two-digit numbers like thirty six', function() { + itoa('36').should.equal('thirty six'); + }); + it('should handle two-digit numbers with a zero in the ones place', function() { + itoa('40').should.equal('forty'); + }); + it('should handle three-digit numbers', function() { + itoa('274').should.equal('two hundred seventy four'); + }); + it('should handle three-digit numbers with a zero in the tens place', function() { + itoa('204').should.equal('two hundred four'); + }); + it('should handle three-digit numbers with a zero in the tens and ones place', function() { + itoa('200').should.equal('two hundred'); + }); + }); + + describe('big numbers', function() { + it('should handle numbers with more than 3 digits', function() { + itoa('14021').should.equal('fourteen thousand twenty one'); + }); + it('should handle numbers with segments of zeroes', function() { + itoa('12000001').should.equal('twelve million one'); + }); + }); + + describe('using "and"', function() { + it('should not insert "and" when requested but uneeded', function() { + itoa('1', true).should.equal('one'); + }); + it('should not insert "and" when requested but uneeded', function() { + itoa('12', true).should.equal('twelve'); + }); + it('should insert "and" when requested', function() { + itoa('112', true).should.equal('one hundred and twelve'); + }); + it('should insert "and" when requested in long numbers', function() { + itoa('12000001', true).should.equal('twelve million and one'); + }); + }); +}); -- cgit v1.2.3