What the what?

I had seen this done before (just do a google search for 'numbers to words javascript' and you'll see solutions all over the place, but it still seemed like a cool idea to do myself. In the end I finished with 50 lines of very readable, very pretty, recursive code.

Sure thats fine and dandy but I thought I could take it further. After some mulling about and a bit of tinkering I was able to get it down to only 8 lines but at the expense of any form of readability. I did this through the (over) usage of the (condition) ? true : false; shorthand for if (condition){ true } else { false }. By using this I was able to get the brunt of the conversion done in only 2 lines.

Heres what the source looks like:

var names = [{"0":"zero","1":"one","2":"two","3":"three","4":"four","5":"five","6":"six","7":"seven","8":"eight","9":"nine" },{"0":"ten","1":"eleven","2":"twelve","3":"thirteen","4":"fourteen","5":"fifteen","6":"sixteen","7":"seventeen","8":"eighteen","9":"nineteen"},{"2":"twenty","3":"thirty","4":"forty","5":"fifty","6":"sixty","7":"seventy","8":"eighty","9":"ninety"},["","thousand","million","billion","trillion","quadrillion","quintillion","sextillion","septillion","octillion","nonillion","decillion","undecillion","duodecillion","tredecillion","quattuordecillion", "quindecillion","sexdecillion","septdecillion","octdecillion","novemdecillion","vigintillion"]];
var to_words = function(s, n){
    var ns = s.slice(0,3);
    return (ns.length < 1)?"":to_words(s.slice(3,s.length),n+1)+((ns.length>1)?((ns.length==3&&ns[2]!="0")?names[0][ns[2]]+" hundred "+((ns[1]=="1")?names[1][ns[0]]+" ":(ns[1]!="0")?names[2][ns[1]]+" "+((ns[0]!="0")?names[0][ns[0]]+" ":""):(ns[0]!="0"?names[0][ns[0]]+" ":"")):((ns[1]=="1")?names[1][ns[0]]+" ":(ns[1]!="0")?names[2][ns[1]]+" "+((ns[0]!="0")?names[0][ns[0]]+" ":""):(ns[0]!="0"?names[0][ns[0]]+" ":""))) + (((ns.length==3&&(ns[0]!="0"||ns[1]!="0"||ns[2]!="0"))||(ns.length==2&&(ns[0]!="0"||ns[1]!="0"))||(ns.length==1&&ns[0]!="0"))?"<span class='magnitude'>"+names[3][n]+"</span> ":""):((ns.length==1&&ns[0]!="0")?names[0][ns[0]]+" ":"") + (((ns.length==3&&(ns[0]!="0"||ns[1]!="0"||ns[2]!="0"))||(ns.length==2&&(ns[0]!="0"||ns[1]!="0"))||(ns.length==1&&ns[0]!="0"))?"<span class='magnitude'>"+names[3][n]+"</span> ":""));
}, input;
document.getElementById('input').addEventListener('keyup', function(){
    document.getElementById('output').innerHTML = to_words(this.value.replace(/[^0-9]/g, '').split('').reverse(), 0);
}, false);

A Quick Example :

If for some reason you come across an incredibly large number such as: 6, 670, 903, 752, 021, 072, 936, 960. You now know that this number is in fact "six sextillion six hundred seventy quintillion nine hundred three quadrillion seven hundred fifty two trillion twenty one billion seventy two million nine hundred thirty six thousand nine hundred sixty"... This as it turns out is the number of possible sudoku puzzles.

More Experiments