1
\$\begingroup\$

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.*;

public class Myriadizer{
    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>0&&binary[bits-1]!=q)output+="myriad ";
        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>4&&binary[bits-5]!=q)output+="quadr"+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[4],"five",strings[0],strings[1],strings[2],strings[3],
                    "ten","eleven","twelve"
            })[t-1]+" ";
            return ;
        }
        if(t<20){
            output+=(new String[]{
                    strings[5],strings[4],strings[6],strings[0],strings[1],strings[2],strings[3]
            })[t-13]+"teen ";
            return ;
        }
        output+=new String[]{"twen",strings[5],"for",strings[6],strings[0],strings[1],strings[2],strings[3]}[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
\$\endgroup\$
8
  • 1
    \$\begingroup\$ The fine details aren't the same as codegolf.stackexchange.com/q/16217/194 , but it's essentially the same question. \$\endgroup\$ Aug 3, 2015 at 19:37
  • \$\begingroup\$ It seems rather distinct from that question to me. \$\endgroup\$ Aug 3, 2015 at 20:03
  • \$\begingroup\$ 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. \$\endgroup\$ Aug 3, 2015 at 21:13
  • \$\begingroup\$ 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. \$\endgroup\$ Aug 3, 2015 at 21:15
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ Aug 3, 2015 at 22:22

2 Answers 2

1
\$\begingroup\$

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[1]));}

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
one hundred myriad
$ ./a.out 1041115
one hundred and four myriad, eleven hundred and fifteen
$ ./a.out 100000000
one myllion
$ ./a.out 1000000501801
one myriad myllion, fifty myriad, eighteen hundred and one
$ ./a.out 94400000123012
ninety-four myriad, forty hundred myllion, twelve myriad, thirty hundred and twelve
$ ./a.out 10000000200000003000000040000000
ten hundred myriad myllion, twenty hundred myriad byllion, thirty hundred myriad myllion, forty hundred myriad
$ ./a.out 100000002000000030000000400000000
one tryllion, two myllion and three byllion, four myllion
\$\endgroup\$
0
\$\begingroup\$

Java, 1477 1459 bytes

import java.math.*;class M{static BigInteger b=new java.util.Scanner(System.in).nextBigInteger(),c=b,k=BigInteger.TEN,d=k.pow(4),f=k.pow(2),e=BigInteger.ZERO;static String o="",s[]={"six","seven","eight","nine","four","thir","fif"},p=" ";static void s(int t){if(t>99){s(t/100);o+="hundred ";if(t%100>0)o+="and ";s(t%100);return;}if(t==0)return;if(t<13){o+=new String[]{"one","two","three",s[4],"five",s[0],s[1],s[2],s[3],"ten","eleven","twelve"}[t-1]+p;return;}if(t<20){o+=new String[]{s[5],s[4],s[6],s[0],s[1],s[2],s[3]}[t-13]+"teen ";return;}o+=new String[]{"twen",s[5],"for",s[6],s[0],s[1],s[2],s[3]}[t/10-2]+"ty";if(t%10>0){o+="-";s(t%10);return;}o+=p;}public static void main(String[]a){if(b.equals(e)){System.out.println("zero");return;}while(c.compareTo(e)>0){int i=0;while(b.compareTo(d)>=0){b=b.divide(d);i++;}char[]z=Integer.toString(i,2).toCharArray();int q=48,l=z.length;String r="yllion ";s(b.intValue());if(l>0&&z[l-1]!=q)o+="myriad ";if(l>1&&z[l-2]!=q)o+="m"+r;if(l>2&&z[l-3]!=q)o+="b"+r;if(l>3&&z[l-4]!=q)o+="tr"+r;if(l>4&&z[l-5]!=q)o+="quadr"+r;if(l>5&&z[l-6]!=q)o+="quint"+r;if(l>6&&z[l-7]!=q)o+="sext"+r;if(l>7&&z[l-8]!=q)o+="sept"+r;if(l>8&&z[l-9]!=q)o+="oct"+r;if(l>9&&z[l-10]!=q)o+="non"+r;if(l>10&&z[l-11]!=q)o+="dec"+r;b=c=c.subtract(d.pow(i).multiply(b));if(b.compareTo(f)>=0)o+=",";o+=p;if(b.compareTo(e)>0&&b.compareTo(f)<0)o+="and ";};System.out.println(o.replaceAll("\\s+$","").replaceAll("\\s\\s+"," ").replaceAll("\\s,",","));}}
\$\endgroup\$
3
  • \$\begingroup\$ This is way too soon to post your own answer. I know it's horribly long, but it may still put people off. \$\endgroup\$
    – Beta Decay
    Aug 3, 2015 at 19:26
  • 11
    \$\begingroup\$ I don't see anything wrong with posting a reference answer. \$\endgroup\$
    – Geobits
    Aug 3, 2015 at 19:41
  • 1
    \$\begingroup\$ @BetaDecay It's only a quickly-golfed version of the Java program in the question. \$\endgroup\$
    – mbomb007
    Aug 4, 2015 at 21:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.