aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--.travis.yml26
-rw-r--r--index.js75
-rw-r--r--lib/digits.js31
-rw-r--r--lib/multipliers.js26
-rw-r--r--lib/utils.js20
-rw-r--r--package.json24
-rw-r--r--test/index.js73
8 files changed, 276 insertions, 0 deletions
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');
+ });
+ });
+});