# Converting integers to English words

The goal of this code golf is to convert integers to English words.

The program prompts for input. If this input isn't an integer, print NaN. If it is an integer, convert it to English words and print these words. Minimum input: 0 (zero). Maximum input: 9000 (nine thousand).
So, 5 returns five (case doesn't matter), and 500 returns five hundred or five-hundred (dashes don't matter).

Some other rules:

A one before hundred or thousand is optional: one hundred is correct, but hundred too (if the input is 100 of course).

The word and in for example one hundred and forty five is optional too.

Whitespace matters. So, for 500, five-hundred or five hundred is correct, but fivehundred is not.

Good luck!

– user9281
Oct 6, 2013 at 18:29
• This answer in SO does similar stuff but isn't code-golf.
– ST3
Oct 7, 2013 at 12:13

## JavaScript (375)

Probably a terrible attempt, but anyway, here goes...

alert(function N(s,z){return O="zero,one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thir,,fif,,,eigh,,,,twen,,for".split(","),(z?O[s]||O[s-10]||O[s-20]:s<13?N(s,1):s<20?N(s,1)+"teen":s<100?N(a=20+(s/10|0),1)+"ty"+(s%10?" "+N(s%10):""):s<1e3?N(s/100|0)+" hundred"+(s%100?" "+N(s%100):""):s<1e5?N(s/1e3|0)+" thousand"+(s%1e3?" "+N(s%1e3):""):0)||NaN}(prompt()))


Pretty-printed (as a function):

function N(s,z) {
return O = "zero,one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thir,,fif,,,eigh,,,,twen,,for".split(","),
(z? O[s] || O[s-10] || O[s-20]
: s < 13?  N(s,1)
: s < 20?  N(s,1) + "teen"
: s < 100? N(a=20+(s/10|0),1) + "ty" + (s%10?" "+N(s%10):"")
: s < 1e3?  N(s/100|0) +  " hundred" + (s%100?" "+N(s%100):"")
: s < 1e5?  N(s/1e3|0) + " thousand" + (s%1e3?" "+N(s%1e3):"") : 0) || NaN
}


Sample conversion (note that it even outputs NaN when out of bounds, i.e. invalid input):

540: five hundred forty
4711: four thousand seven hundred eleven
7382: seven thousand three hundred eighty two
1992: one thousand nine hundred ninety two
hutenosa: NaN
1000000000: NaN
-3: NaN

• +1 its quite difficult to do better in a language like javascript. (you can remove the space in N(s,z) {return to save 1 char) Oct 13, 2013 at 11:04
• Oh, haha, must've missed that one. I also seem to have missed a bunch of chars in the O string. I'll fix that.. Oct 13, 2013 at 13:09

# Mathematica 60 57

f = ToString@#~WolframAlpha~{{"NumberName", 1}, "Plaintext"} &


Usage:

f[500]


five hundred

Edit:

InputString[]~WolframAlpha~{{"NumberName", 1}, "Plaintext"}

• This doesn't really answer the question. I said that the user has to input a number (using the command line, or a prompt box for example), and then your program should output the words (on the command line, or in a message box for example). Your code is just a function to convert it, and your program doesn't ask for input. Oct 10, 2013 at 15:37
• @ProgramFOX it says 'The user inputs something'. That does not mean 'The program prompts for input'. Oct 11, 2013 at 17:33
• @MrZander: Well, 'The program prompts for input' was actually what I meant. I update my question, but of course, it would be unfair if I wouldn't upvote alephalpha's answer, so he got my +1 Oct 12, 2013 at 13:48

# Lisp, 72 56 characters

I realize 1) that this is old, and 2) that it relies entirely on the standard library to function, but the fact that you can get the c-lisp printing system to do this kind of thing has always impressed me. Also, this does in fact take the input from a user, convert it, and print it.

(format t "~:[NaN~;~:*~r~]" (parse-integer (read-line) :junk-allowed t))


It totals 72 characters.

• :junk-allowed causes parse-integer to return nil on failure instead of raising an error.
• ~:[if-nil~;if-non-nill] conditional predicated on nil, handles NaN where necessary
• ~:* backs up the argument interpretation to re-consume the input
• ~r prints the number as an english word string, as requested, except with full corrected punctuation

Sample:

17823658
seventeen million, eight hundred and twenty-three thousand, six hundred and fifty-eight

192hqfwoelkqhwef9812ho1289hg18hoif3h1o98g3hgq
NaN


Lisp info mainly from Practical Common Lisp.

## Edit, golfed properly down to 56 characters

(format t "~:[NaN~;~:*~r~]"(ignore-errors(floor(read))))


This version works rather differently. Instead of reading a line and converting it, it invokes the lisp reader to interpret the input as a lisp s-expression, attempts to use it as a number, and if any errors are produced ignores them producing nil to feed the format string conditional. This may be the first instance I've seen of lisp producing a truly terse program... Fun!

• (read) Invokes the lisp reader/parser to read one expression from standard input and convert it into an appropriate object
• (floor) attempts to convert any numeric type into the nearest lower integer, non-numeric types cause it to raise an error
• (ignore-errors ...) does what it says on the tin, it catches and ignores any errors in the enclosed expression, returning nil to feed the NaN branch of the format string
• It's certainly no problem that the question old :) I edited your answer to include the language name and the character count in a header. Jan 10, 2015 at 9:53
• Thank you for the edits, I haven't gotten the Stack* syntax for these things down yet. Went back in and fixed a mistake I made in the description of the conditional in the format string as well. Jan 12, 2015 at 18:07

## Perl 281 bytes

print+0eq($_=<>)?Zero:"@{[((@0=($z,One,Two,Three,Four,Five,@2=(Six,Seven),
Eight,Nine,Ten,Eleven,Twelve,map$_.teen,Thir,Four,@1=(Fif,@2,Eigh,Nine))) [$_/1e3],Thousand)x($_>999),($0[($_%=1e3)/100],Hundred)x($_>99),
($_%=100)>19?((Twen,Thir,For,@1)[$_/10-2].ty,$0[$_%10]):$0[$_]]}"||NaN


Newlines added for horizontal sanity. The above may be used interactively, or by piping it a value via stdin.

Works correctly for all integer values on the range [0, 19999], values outside this range exhibit undefined behavior. Non-integer values will be truncated towards zero, and as such, only values which are truly non-numeric will report NaN.

Sample usage:

for $n (14, 42, 762, 2000, 6012, 19791, 1e9, foobar, 17.2, -3) { print "$n: ", echo $n | perl spoken-numbers.pl,$/;
}


Sample output:

14: Fourteen
42: Forty Two
762: Seven Hundred Sixty Two
2000: Two Thousand
6012: Six Thousand Twelve
19791: Nineteen Thousand Seven Hundred Ninety One
1000000000: Thousand
foobar: NaN
17.2: Seventeen
-3: Nine Hundred Ninety Seven

• "1000000000: Thousand "? And shouldn't 17.2 print "NaN"? Oct 11, 2013 at 17:46
• @DavidCarraher "... values outside this range exhibit undefined behavior. Non-integer values will be truncated towards zero, and as such, only values which are truly non-numeric will report NaN." Oct 12, 2013 at 4:20
• I'm not a Perl expert, so I ask this question: does this program prompt for input? Oct 14, 2013 at 17:48
• @ProgramFOX I have updated it to read a value from stdin (if run interactively, it will prompt the user for a value), instead of as a function. Oct 15, 2013 at 6:15

# PHP, 327310 308 bytes

<?$a=['',one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thir,0,fif,0,0,eigh];echo($n=$argv[1])>999?$a[$n/1000].' thousand ':'',$n%1000>99?$a[$n/100%10].' hundred ':'',$n?($k=$n%100)<20?($a[$k]?:$a[$k%10]).[teen][$k<13]:[2=>twen,thir,'for',fif,six,seven,eigh,nine][$k/10].'ty '.$a[$k%10]:zero;  takes the number as parameter, works for 0<=n<=12999 breakdown // define names$a=['',one,two,three,four,five,six,seven,eight,nine,
ten,eleven,twelve,thir,0,fif,0,0,eigh];
// print ...
echo
($n=$argv[1])>999?$a[$n/1000].' thousand ':'',                  // thousands
$n%1000>99?$a[$n/100%10].' hundred ':'', // hundreds$n?
// if remains <20:
($k=$n%100)<20?
($a[$k]?:$a[$k%10]) // no value at index (0,14,16,17,19)? value from index%10
.[teen][$k<13] // append "teen" for$k>12
// else:
:[2=>twen,thir,'for',fif,six,seven,eigh,nine][$k/10].'ty ' // tens .$a[$k%10] // ones // "zero" for$n==0
:zero
;


# SAS, 70 characters

data;window w n;display w;if n=. then put 'NaN';else put n words.;run;


The window and display statements open up the SAS command prompt. Input for n goes on line 1. This takes advantage of the SAS format words. which will print the number as a word or series of words with "and", " ", and "-" as appropriate.

PHP

777 characters

This is definitely a terrible attempt, but you can't accuse me of taking advantage of any loopholes, plus it's a very lucky number. Thanks to ProgramFOX for the tip.

<?php $i=9212;$b = array('zero','one','two','three','four','five','six','seven','eight','nine');$t='teen';$c = array('ten','eleven','tweleve','thir'.$t,$b[4].$t,'fif'.$t,$b[6].$t,$b[7].$t,$b[8].$t,$b[9].$t);$d = array('','','twenty','thirty','fourty','fifty','sixty','seventy','eighty','ninety');$e='hundred';$f='thousand';$j=str_split($i);if (strlen($i)===1){$a=$b[$i];}elseif (strlen($i)===3){$k=1;$a=$b[$j[0]].' '.$e.' '.x($j,$k);}elseif (strlen($i)===4){$k=2;$a=$b[$j[0]].' '.$f.' '.$b[$j[1]].' '.$e.' '.x($j,$k);}elseif (substr($i, -2, 1)==='1'){$a=$c[$j[1]];}else{$a=$d[$j[0]].' '.$b[$j[1]];}$a = str_replace('zero hundred','',$a);echo$a;function x($j,$k){global $i,$b, $c,$d;if (substr($i, -2, 1)==='1'){return$c[$j[$k+1]];}else{return $d[$j[$k]].' '.$b[$j[$k+1]];}}


Long hand

<?php
// Input
$i=9212; // 0-9$b = array('zero','one','two','three','four','five','six','seven','eight','nine');
// 10-19 (Very tricky)
$t='teen';$c = array('ten','eleven','tweleve','thir'.$t,$b[4].$t,'fif'.$t,$b[6].$t,$b[7].$t,$b[8].$t,$b[9].$t);
// Left digit of 20-99
$d = array('','','twenty','thirty','fourty','fifty','sixty','seventy','eighty','ninety'); // Hundreds$e='hundred';
// Thousands
$f='thousand'; // Split input$j=str_split($i); // 1 digit inputs if (strlen($i)===1){$a=$b[$i];} // 3 digit input elseif (strlen($i)===3){$k=1;$a=$b[$j[0]].' '.$e.' '.x($j,$k);} // 4 digit input elseif (strlen($i)===4){$k=2;$a=$b[$j[0]].' '.$f.' '.$b[$j[1]].' '.$e.' '.x($j,$k);}
// 10-19
elseif (substr($i, -2, 1)==='1'){$a=$c[$j[1]];}
// 20-99
else{$a=$d[$j[0]].' '.$b[$j[1]];} // Fix for thousand numbers$a = str_replace('zero hundred','',$a); // Result echo$a;
// Abstracted function last 2 digits for 3 and 4 digit numbers
function x($j,$k){
global $i,$b, $c,$d;
// 10-19
if (substr($i, -2, 1)==='1'){return$c[$j[$k+1]];}
// 20-99
else{return $d[$j[$k]].' '.$b[$j[$k+1]];}
}

• I think you can shorten your code by creating arrays like this: array('zero','one','two'). Jun 26, 2015 at 13:44
• @ProgramFOX or even ['zero','one','two'] (php 5.4+). And if you don't mind E_NOTICE, [zero,one,two] would work as well. Jun 26, 2015 at 21:50
• I should update it, but 777 is such a lucky number. Jun 26, 2015 at 22:06
• +1 for your efforts. PHP is tragically underrepresented in code golf. Jun 27, 2015 at 5:55

# Python 2.x - 378

Derivative of Fireflys answer, although by changing P to include million or trillions, etc.. it could recursively be used for any range of positive numbers. This also supports values up to 999,999

O=",one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thir,,fif,,,eigh,,,,twen,thir,for,fif,,,eigh,".split(",")
P=",thousand".split(',')
def N(s,p=0):
h,s=divmod(s,1000);x=N(h,p+1)if h>0 else" "
if s<20:x+=O[s]or O[s-10]+["","teen"][s>12]
elif s<100:x+=(O[s/10+20]or O[s/10])+"ty"+N(s%10)
else:x+=N(s/100)+"hundred"+N(s%100)
return x+" "+P[p]
print N(input())


Sample test (input is <<<, output is >>>):

<<< 1234
>>> one thousand two hundred thirty four

<<< 999999
>>>  nine hundred ninety nine   thousand nine hundred ninety nine


Although, if someone can explain this odd "buffer underflow" issue I have, that'd be swell...

<<< -1
>>>  nine hundred ninety nine

<<< -2
>>>  nine hundred ninety eight

• print divmod(-2,1000) #-> (-1, 998) Oct 10, 2013 at 7:38
• Oh of course. I was thinking it might take an absolute value or something. But there is -1*1000 and a "remainder" of 998.
– user8777
Oct 10, 2013 at 8:57

# SmileBASIC, 365 Three Hundred Forty Seven bytes

DIM N$[22]D$="OneTwoThreeFourFiveSixSevenEightNineTenElevenTwelveThirFourFifSixSevenEighNineTwenFor
WHILE LEN(D$)INC I,D$[0]<"_
INC N$[I],SHIFT(D$)WEND
INPUT N
W=N MOD 100C%=N/100MOD 10M%=N/1E3T=W<20X=W/10>>0?(N$[M%]+" Thousand ")*!!M%+(N$[C%]+" Hundred ")*!!C%+(N$[X+10+(X==2)*8+(X==4)*7]+"ty "+N$[N MOD 10])*!T+N$[W*T]+"teen"*(T&&W>12)+"Zero"*!N  There's a trailing space if the last one or two digits are 0. # Vyxal, 11 bytes ⌈≠[NaN|∆ċ  Try it Online! Easy win when it's a built-in :p • @Lynn now it does Sep 20, 2022 at 12:16 • If you use 2.16.x or something kn works? Nov 24, 2022 at 5:15 # Wolfram Language 27 40 bytes Making use of the native function, IntegerName,  Check[Input[]~IntegerName~"Words","NaN"]  The above prompts for user input. The present implementation returns "NaN" if the user enters anything other than an integer. Some examples (with pre-set inputs):  Check[243~IntegerName~"Words","NaN"]  two hundred forty-three  Check[1234567890~IntegerName~"Words","NaN"]  one billion, two hundred thirty-four million, five hundred sixty-seven thousand, eight hundred ninety  Check["abc"~IntegerName~"Words","NaN"]  NaN # Python 2, 333 bytes def f(n):S=str.split;D=S('z one two three four five six seven eight nine');K=' fif six seven eigh nine';k=n/1000;n,m=n/100%10,n%100;e,d=m/10,m%10;return' '.join([k and f(k),'thousand']*(k>0)+[D[n],'hundred']*(n>0)+([S('ten eleven twelve thir four'+K)[d]+'teen'*(d>2)]if 9<m<20else[S('twen thir for'+K)[e-2]+'ty']*(e>0)+[D[d]]*(d>0)))  Try it online! This is good for 1 to 999,999, inclusive. # Pyth, 239 242 bytes L:rjdb6" +"dAm+cd;"nine"," one two three four five six seven eight"" twen thir for fif six seven eigh"|y_.ey+Wk.e?Y?thZjd,?hZ+@HhZ"ty"""@GeZ@+c"ten eleven twelve"d+R"teen"+c"thir four"d>H5eZ?hZ+@GhZ" hundred"""c.[03_b]1"thousand"c_jQT3"zero  Input is an integer in range [0-999,999]. Try it online here. Explanation pending. Previous version, very similar operation, but doesn't support 0: L:rjdb6" +"dJc" one two three four five six seven eight nine"dKc" twen thir for fif six seven eigh nine"dy_.ey+Wk.e?Y?thZjd,?hZ+@KhZ"ty"""@JeZ@+c"ten eleven twelve"d+R"teen"+c"thir four"d>K5eZ?hZ+@JhZ" hundred"""c.[03_b]1"thousand"c_jQT3  Explanation of previous version: Implicit: Q=eval(input()), d=" " Step 1: output formatting helper function L:rjdb6" +"d L Define a function, y(b): jdb Join b on spaces r 6 Strip whitespace from beginning and end : In the above, replace... " +" ... strings of more than one space... d ... with a single space Step 2: Define number lookup lists Jc"..."dKc"..."d "..." Lookup string c d Split the above on spaces J Store in J - this is list of unit names Kc"..."d As above, but storing in K - this is list of tens names, without "ty" Step 3: Bringing it all together y_.ey+Wk.e?Y?thZjd,?hZ+@KhZ"ty"""@JeZ@+c"ten eleven twelve"d+R"teen"+c"thir four"d>K5eZ?hZ+@JhZ" hundred"""c.[03_b]1"thousand"c_jQT3 jQT Get digits of Q _ Reverse c 3 Split into groups of 3 .e Map the above, element as b, index as k, using: _b Reverse the digits in the group .[03 Pad the above on the left with 0 to length 3 c ]1 Chop at index 1 - [1,2,3] => [[1],[2,3]] .e Map the above, element as Z, index as Y, using: ?Y If second element in the group (i.e. tens and units): ?thZ If (tens - 1) is non-zero (i.e. 0 or >=2): ?hZ If tens is non-zero: @KhZ Lookup in tens names + "ty" Append "ty" Else: "" Empty string , Create two-element list of the above with... @JeZ ... lookup units name jd Join the above on a space - this covers [0-9] and [20-99] Else: c"thir four"d ["thir", "four"] + >K5 Append last 5 element of tens names ("fif" onwards) +R"teen" Append "teen" to each string in the above +c"ten eleven twelve"d Prepend ["ten", "eleven", "twelve"] @ eZ Take string at index of units column - this covers [10-19] Else: (i.e. hundreds column) ?hZ If hundreds column is non-zero: @JhZ Lookup units name + " hundred" Append " hundred" "" Else: empty string Result of map is two element list of [hundreds name, tens and units name] Wk If k is nonzero (i.e. dealing with thousands group)... + "thousand" ... Append "thousand" y Apply output formatting (join on spaces, strip, deduplicate spaces) Result of map is [units group string, thousands group string] _ Reverse group ordering to put thousands back in front y Apply output formatting again, implicit print  # MOO - 55 83 bytes x=$code_utils:toint(read(p=player));p:tell(x==E_TYPE?"NaN"|\$string_utils:english_number(x))


Note: this code does not print any prompt to the standard output.

As a bonus, this code can handle any number withing the bounds of the moo language (2147483647--2147483648).