import java.math.*;
/** A class to obtain the English language name of an arbitrary precision integer.
*
This class should support all conceivable BigIntegers, limited only by the length of the name itself.
*/
public class EnglishNumberNames{
//Vocabulary
private static final String[] smallVocabulary={"","one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety"};
private static final String[] largeVocabulary={"","thousand","million","billion","trillion","quadrillion","quintillion","sextillion","septillion","octillion","nonillion"};
private static final String[] largeVocabulary0={"","un","duo","tre","quattuor","quin","sex","septen","octo","novem"};
private static final String[] largeVocabulary1={"","dec","vigin","trigin","quadragin","quinquagin","sexagin","septuagin","octogin","nonagin"};
private static final String[] largeVocabulary2={"","cen","duocen","trecen","quadringen","quingen","sescen","septingen","octingen","nongen"};
//name of a number from 1 to 999
private static String shortname(int n){
n=n%1000;
if(n<20){return smallVocabulary[n];}
if(n<100){return smallVocabulary[((n/10)%10)+18]+(n%10==0?"":" ")+smallVocabulary[n%10];}
return smallVocabulary[n/100]+" hundred"+(n%100==0?"":" ")+shortname(n%100);
}
//proper short scale word for 1000^n
private static String thousandsPower(long n){
if(n<0){throw new ArithmeticException("negative powers unsupported");}
if(n<=10){return largeVocabulary[(int)n];}n--;
String pow="";
String millias="";
int suffix=(int)((n/10)%10);
while(n>0){
int x=(int)(n%1000);
n/=1000;
pow=(x==0?"":millias)+pow;
pow=largeVocabulary1[(x/10)%10]+pow;
if(!(n==0&&x==1)){pow=largeVocabulary0[x%10]+pow;}
pow=largeVocabulary2[x/100]+pow;
millias+="millia";
}
return pow+(suffix==1?"illion":"tillion");
}
/** Returns the English short scale name for the given BigInteger n.*/
public static String name(BigInteger n){
return name(n,0);
}
/** Returns the English short scale name for the BigInteger n*1000^off.
*
This method allows the naming of large numbers without storing the trailing zeroes.
*/
public static String name(BigInteger n,long off){
if(off<0){throw new ArithmeticException("negative offset");}
if(n.signum()==0){return "zero";}
if(n.signum()==-1){return "negative "+name(n.negate(),off);}
int part=0; String s="";
while(n.signum()>0){
part=n.remainder(BigInteger.valueOf(1000)).intValue();
n=n.divide(BigInteger.valueOf(1000));
if(off>0&&part>0){s=" "+thousandsPower(off)+s;}
s=shortname(part)+s;
if(n.signum()>0&&part>0){s=" "+s;}
off++;
}
return s;
}
public static void main(String[] args){
for(int c=0;c<=11159;c++){
String nom=name(BigInteger.valueOf(c)).replace(" ","");
System.out.println(c+" "+nom.length());
}
}
}