Name a number using the Myriad System!

The Myriad System is an alternative system for naming large numbers proposed by Donald Knuth in 1981.

In this system, numbers up to 999 are named as they are normally, but 1000 is not given a special name and is instead named as "ten hundred"; the next benchmark number being 10000, or "one myriad" (which, of course, comes from an ancient greek word meaning 10000).

From here one myllion is defined as one myriad * one myriad, one byllion as one myllion * one myllion, one tryllion as one byllion * one byllion, and so forth.

The challenge here is to take a base-10 integer from the input and determine its name in this system.

Your input is guaranteed to be nonnegative and less than 10212=104096 (one decyllion)

Either a full program (in which case input can be taken from either stdin or a command line argument, and output must be sent to stdout) or a function (which takes the input as an argument and returns the output) is permissible.

The returned string should be formatted as per this Java program:

import java.math.*;

static BigInteger b=new java.util.Scanner(System.in).nextBigInteger(),c=b,TEN=BigInteger.TEN,d=TEN.pow(4),f=TEN.pow(2),e=BigInteger.ZERO;
static String[]strings={"six","seven","eight","nine","four","thir","fif"};
static String output="";
static void t(){
int i=0;
while(b.compareTo(d)>=0){
b=b.divide(d);
i++;
}
int k=b.intValue();
char[]binary=Integer.toString(i,2).toCharArray();
int q=48,bits=binary.length;
String r="yllion ";
s(k);
if(bits>1&&binary[bits-2]!=q)output+="m"+r;
if(bits>2&&binary[bits-3]!=q)output+="b"+r;
if(bits>3&&binary[bits-4]!=q)output+="tr"+r;
if(bits>5&&binary[bits-6]!=q)output+="quint"+r;
if(bits>6&&binary[bits-7]!=q)output+="sext"+r;
if(bits>7&&binary[bits-8]!=q)output+="sept"+r;
if(bits>8&&binary[bits-9]!=q)output+="oct"+r;
if(bits>9&&binary[bits-10]!=q)output+="non"+r;
if(bits>10&&binary[bits-11]!=q)output+="dec"+r;
b=c=c.subtract(d.pow(i).multiply(b));
if(b.compareTo(f)>=0)output+=",";
output+=" ";
if(b.compareTo(e)>0&&b.compareTo(f)<0)output+="and ";
}
static void s(int t){
if(t>99){
s(t/100);
output+="hundred ";
if(t%100>0)output+="and ";
s(t%100);
return ;
}
if(t==0)return;
if(t<13){
output+=(new String[]{
"one","two","three",
strings,"five",strings,strings,strings,strings,
"ten","eleven","twelve"
})[t-1]+" ";
return ;
}
if(t<20){
output+=(new String[]{
strings,strings,strings,strings,strings,strings,strings
})[t-13]+"teen ";
return ;
}
output+=new String[]{"twen",strings,"for",strings,strings,strings,strings,strings}[t/10-2]+"ty";
if(t%10>0){
output+="-";
s(t%10);
return;
}
output+=" ";
}
public static void main(String[]a){if(b.equals(e)){System.out.println("zero");return;}while(c.compareTo(e)>0)t();System.out.println(output.replaceAll("\\s+$","").replaceAll("\\s\\s+"," ").replaceAll("\\s,",","));} } Some details of this that should be noted: • The terms in the main sum should be arranged in descending order • The terms in any given product should be arranged in ascending order, and exactly one term in any given product should be under one myriad • The terms in the main sum should be comma-separated, unless the last is under one hundred in which case the last two should be separated by the conjunction "and" This is code golf, so the shortest program wins. Some test cases: 0 = zero 100 = one hundred 1000 = ten hundred 10014 = one myriad and fourteen 19300 = one myriad, ninety-three hundred 100000 = ten myriad 1000000 = one hundred myriad 1041115 = one hundred and four myriad, eleven hundred and fifteen 100000000 = one myllion 1000000501801 = one myriad myllion, fifty myriad, eighteen hundred and one 94400000123012 = ninety-four myriad myllion, forty hundred myllion, twelve myriad, thirty hundred and twelve 10000000200000003000000040000000 = ten hundred myriad myllion byllion, twenty hundred myriad byllion, thirty hundred myriad myllion, forty hundred myriad 100000002000000030000000400000000 = one tryllion, two myllion byllion, three byllion, four myllion • The fine details aren't the same as codegolf.stackexchange.com/q/16217/194 , but it's essentially the same question. – Peter Taylor Aug 3 '15 at 19:37 • It seems rather distinct from that question to me. – SuperJedi224 Aug 3 '15 at 20:03 • At first it seemed laughable that Knuth invented something special with the Myriad System: the word myriad is ancient and the Chinese always use myriads rather than thousands. But once I understood I realised I underestimated the great man. According to the definition 10000000 20000000 30000000 40000000 is 1 byllion 2 myllion tryllion, 3 byllion 4 myllion. It implies a recursive algorithm where the number is split in half and each half is named separately. This is unlike other number systems. @PeterTaylor I'm open voting, but not upvoting because it's close to the latest question asked. – Level River St Aug 3 '15 at 21:13 • I think you should make it clearer that 1 tryllion is 1 byllion * 1 byllion and 1 quadryllion is 1 tryllion * 1 tryllion. The fact that 1byllion * = 1 myllion * 1 myllion is as far as your text goes, and does not demonstrate any departure from the normal long scale system. – Level River St Aug 3 '15 at 21:15 • so the word byllion has to be repeated, even though it is understandable without? what about one hundred one myriad one hundred million? where do repeated words have to be used, and where do commas and ands have to be used? The spec should be in English, not Java. This has always been a rule here, reference implementations do not constitute a spec. Please clarify in the question. – Level River St Aug 3 '15 at 22:22 2 Answers C, 698 bytes Recursive approach, don't mind the memory leaks :) Explanation to come later. #include <stdlib.h> #define c char* n;c r(c v){c p,*z,*o[]={"","one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen","twen","thir","for","fif","six","seven","eigh","nine","hundred","myriad","m","b","tr","quadr","quint","sext","sept","oct","non","dec"};int s,l;long t;v+=strspn(v,"0");l=strlen(v);if(l<3)n=atoi(v),n<20?p=o[n],0:asprintf(&p,n%10?"%sty-%s":"%sty",o[n/10+18],o[n%10]);else s=(int)(log(l-1)/log(2))-1,z=v+l-(2<<s),t=strtol(z,0,10),p=r(z),*z=0,asprintf(&p,*p?"%s %s%s%s %s":"%s %s%s",r(v),o[s+28],s>1?"yllion":"",*p?t<100?" and":",":"",p);return p;}main(_,v)c*v;{puts(r(v));} Examples$ ./a.out 0
zero
$./a.out 100 one hundred$ ./a.out 1000
ten hundred
$./a.out 10014 one myriad and fourteen$ ./a.out 19300
one myriad, ninety-three hundred
$./a.out 100000 ten myriad$ ./a.out 1000000
$./a.out 1041115 one hundred and four myriad, eleven hundred and fifteen$ ./a.out 100000000
$./a.out 1000000501801 one myriad myllion, fifty myriad, eighteen hundred and one$ ./a.out 94400000123012
$./a.out 10000000200000003000000040000000 ten hundred myriad myllion, twenty hundred myriad byllion, thirty hundred myriad myllion, forty hundred myriad$ ./a.out 100000002000000030000000400000000