28
\$\begingroup\$

Here's a simple one to stretch your compression muscles. Your code (a complete program) must output the spelled-out English representation of all the cardinal numbers from 1 to 100, and then all the ordinal numbers from 1 to 100. The numerals in each list should be delimited by commas and spaces and properly hyphenated. Each list should begin with a single capital letter and conclude with a period. The two lists should be separated by a newline.

For clarity's sake, you must produce this exact byte stream:

One, two, three, four, five, six, seven, eight, nine, ten, eleven, twelve, thirteen, fourteen, fifteen, sixteen, seventeen, eighteen, nineteen, twenty, twenty-one, twenty-two, twenty-three, twenty-four, twenty-five, twenty-six, twenty-seven, twenty-eight, twenty-nine, thirty, thirty-one, thirty-two, thirty-three, thirty-four, thirty-five, thirty-six, thirty-seven, thirty-eight, thirty-nine, forty, forty-one, forty-two, forty-three, forty-four, forty-five, forty-six, forty-seven, forty-eight, forty-nine, fifty, fifty-one, fifty-two, fifty-three, fifty-four, fifty-five, fifty-six, fifty-seven, fifty-eight, fifty-nine, sixty, sixty-one, sixty-two, sixty-three, sixty-four, sixty-five, sixty-six, sixty-seven, sixty-eight, sixty-nine, seventy, seventy-one, seventy-two, seventy-three, seventy-four, seventy-five, seventy-six, seventy-seven, seventy-eight, seventy-nine, eighty, eighty-one, eighty-two, eighty-three, eighty-four, eighty-five, eighty-six, eighty-seven, eighty-eight, eighty-nine, ninety, ninety-one, ninety-two, ninety-three, ninety-four, ninety-five, ninety-six, ninety-seven, ninety-eight, ninety-nine, one hundred.
First, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, eleventh, twelfth, thirteenth, fourteenth, fifteenth, sixteenth, seventeenth, eighteenth, nineteenth, twentieth, twenty-first, twenty-second, twenty-third, twenty-fourth, twenty-fifth, twenty-sixth, twenty-seventh, twenty-eighth, twenty-ninth, thirtieth, thirty-first, thirty-second, thirty-third, thirty-fourth, thirty-fifth, thirty-sixth, thirty-seventh, thirty-eighth, thirty-ninth, fortieth, forty-first, forty-second, forty-third, forty-fourth, forty-fifth, forty-sixth, forty-seventh, forty-eighth, forty-ninth, fiftieth, fifty-first, fifty-second, fifty-third, fifty-fourth, fifty-fifth, fifty-sixth, fifty-seventh, fifty-eighth, fifty-ninth, sixtieth, sixty-first, sixty-second, sixty-third, sixty-fourth, sixty-fifth, sixty-sixth, sixty-seventh, sixty-eighth, sixty-ninth, seventieth, seventy-first, seventy-second, seventy-third, seventy-fourth, seventy-fifth, seventy-sixth, seventy-seventh, seventy-eighth, seventy-ninth, eightieth, eighty-first, eighty-second, eighty-third, eighty-fourth, eighty-fifth, eighty-sixth, eighty-seventh, eighty-eighth, eighty-ninth, ninetieth, ninety-first, ninety-second, ninety-third, ninety-fourth, ninety-fifth, ninety-sixth, ninety-seventh, ninety-eighth, ninety-ninth, one hundredth.

This is code golf, shortest answer in bytes wins.

\$\endgroup\$

11 Answers 11

28
\$\begingroup\$

Common Lisp, 88 82 80 bytes

(format t"~@(~{~R~^, ~}~).
~:*~@(~{~:R~^, ~}~)."(loop as i to 99 collect(1+ i)))

(It is part of the language, I hope you don't mind)

Output

One, two, three, four, five, six, seven, eight, nine, ten, eleven, twelve, thirteen, fourteen, fifteen, sixteen, seventeen, eighteen, nineteen, twenty, twenty-one, twenty-two, twenty-three, twenty-four, twenty-five, twenty-six, twenty-seven, twenty-eight, twenty-nine, thirty, thirty-one, thirty-two, thirty-three, thirty-four, thirty-five, thirty-six, thirty-seven, thirty-eight, thirty-nine, forty, forty-one, forty-two, forty-three, forty-four, forty-five, forty-six, forty-seven, forty-eight, forty-nine, fifty, fifty-one, fifty-two, fifty-three, fifty-four, fifty-five, fifty-six, fifty-seven, fifty-eight, fifty-nine, sixty, sixty-one, sixty-two, sixty-three, sixty-four, sixty-five, sixty-six, sixty-seven, sixty-eight, sixty-nine, seventy, seventy-one, seventy-two, seventy-three, seventy-four, seventy-five, seventy-six, seventy-seven, seventy-eight, seventy-nine, eighty, eighty-one, eighty-two, eighty-three, eighty-four, eighty-five, eighty-six, eighty-seven, eighty-eight, eighty-nine, ninety, ninety-one, ninety-two, ninety-three, ninety-four, ninety-five, ninety-six, ninety-seven, ninety-eight, ninety-nine, one hundred.
First, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, eleventh, twelfth, thirteenth, fourteenth, fifteenth, sixteenth, seventeenth, eighteenth, nineteenth, twentieth, twenty-first, twenty-second, twenty-third, twenty-fourth, twenty-fifth, twenty-sixth, twenty-seventh, twenty-eighth, twenty-ninth, thirtieth, thirty-first, thirty-second, thirty-third, thirty-fourth, thirty-fifth, thirty-sixth, thirty-seventh, thirty-eighth, thirty-ninth, fortieth, forty-first, forty-second, forty-third, forty-fourth, forty-fifth, forty-sixth, forty-seventh, forty-eighth, forty-ninth, fiftieth, fifty-first, fifty-second, fifty-third, fifty-fourth, fifty-fifth, fifty-sixth, fifty-seventh, fifty-eighth, fifty-ninth, sixtieth, sixty-first, sixty-second, sixty-third, sixty-fourth, sixty-fifth, sixty-sixth, sixty-seventh, sixty-eighth, sixty-ninth, seventieth, seventy-first, seventy-second, seventy-third, seventy-fourth, seventy-fifth, seventy-sixth, seventy-seventh, seventy-eighth, seventy-ninth, eightieth, eighty-first, eighty-second, eighty-third, eighty-fourth, eighty-fifth, eighty-sixth, eighty-seventh, eighty-eighth, eighty-ninth, ninetieth, ninety-first, ninety-second, ninety-third, ninety-fourth, ninety-fifth, ninety-sixth, ninety-seventh, ninety-eighth, ninety-ninth, one hundredth.

Explanations

See Formatted Output to Character Streams.

  • (format t "<control string>" <arguments>) formats the control string according to the (variadic) arguments and prints to standard output (because t)

  • (loop ...) builds the list of integers from 1 to 100

  • ~@( ... ~) capitalizes the string returned by the inner control string
  • ~{ ... ~} iterates over the current argument and applies the inner formatting to each element
  • Inside the iteration, everything that follows ~^ is not printed on the last iteration: this is used to add the comma-space separator between elements.
  • ~R outputs current argument as a cardinal
  • ~:R outputs current argument as an ordinal
  • ~% outputs a new line
  • ~:* reset the current argument to be processed as the previous one, which is used here to reuse the list of integers a second time.

Saved 2 bytes thanks to PrzemysławP.

\$\endgroup\$
  • 1
    \$\begingroup\$ And I thought my 340-byte answer was impressive... \$\endgroup\$ – kirbyfan64sos Sep 5 '15 at 0:12
  • 3
    \$\begingroup\$ Your rep at this moment is pretty 1337! :D So, unfortunately, I cannot upvote this solution... :( \$\endgroup\$ – Numeri says Reinstate Monica Sep 5 '15 at 0:15
  • 2
    \$\begingroup\$ @Numeri You can upvote now. ;) \$\endgroup\$ – DLosc Sep 5 '15 at 4:46
  • 1
    \$\begingroup\$ Solutions shorted than the kolomogorov complexity of the input are always very impressive! Well done. \$\endgroup\$ – isaacg Sep 5 '15 at 5:31
  • 1
    \$\begingroup\$ @DLosc It was just to good for me to break... :D \$\endgroup\$ – Numeri says Reinstate Monica Sep 5 '15 at 16:02
9
\$\begingroup\$

Pyth, 366 342 340 bytes

Lcbdj=Y", "++rhJy"one two three four five six seven eight nine"3+tJ+y"ten eleven twelve"+=Nm+d"teen"=by"thir four fif six seven eigh nine"sm+dm++d\-kJKy"twenty thirty forty fifty sixty seventy eighty ninety"+=H"one hundred"\.jY+rh=J++y"first second third"m+d=T"th"tPby"ninth"3+++tJy"tenth eleventh twelfth"+m+dTNsm++Pd"ieth"m++d\-kJK+H"th."

Live demo.

342-byte version:

Lcbdj", "++rhJy"one two three four five six seven eight nine"3+tJ+y"ten eleven twelve"+=Nm+d"teen"=by"thir four fif six seven eigh nine"sm+dm++d\-kJKy"twenty thirty forty fifty sixty seventy eighty ninety"+=H"one hundred"\.j", "+rh=J++y"first second third"m+d"th"tPby"ninth"3+++tJy"tenth eleventh twelfth"+m+d"th"Nsm++Pd"ieth"m++d\-kJK+H"th."

366-byte version:

Lcbd
j", "++"One"+tJy"one two three four five six seven eight nine"+y"ten eleven twelve"+=Nm+d"teen"y"thir four fif six seven eigh nine"sm+dm++d\-kJKy"twenty thirty forty fifty sixty seventy eighty ninety"+=H"one hundred"\.
j", "+"First"+++t=Jy"first second third fourth fifth sixth seventh eighth ninth"y"tenth eleventh twelfth"+m+d"th"Nsm++Pd"ieth"m++d\-kJK+H"th."
\$\endgroup\$
6
\$\begingroup\$

PHP - 491 bytes

Small cheat here for the cardinals (I'm using the NumberFormatter class that comes default with PHP):

echo'One, ';$x=new NumberFormatter(0,5);for($i=1;$i++<100;)echo$x->format($i).($i>99?
'.':', ');echo"
";$y=[First,second,third,fourth,fifth,sixth,seventh,eighth,ninth,tenth,
eleventh,twelfth,thirteenth,fourteenth,fifteenth,sixteenth,seventeenth,eighteenth,nineteenth,
twentieth];for($z=[thirtieth,fortieth,fiftieth,sixtieth,seventieth,eightieth,ninetieth];
$j++<99;$q=floor($j/10),$w=$z[$q-2])echo$j<21?$y[$j-1]:($j%10?$x->format($q*10).'-'.
strtolower($y[$j%10-1]):$w),', ';echo'one hundredth.';

(added a few new lines for readability)

\$\endgroup\$
  • 2
    \$\begingroup\$ Warnings are generally allowed, remove all the @ (-4 bytes). Use a newline instead of writing \n (-1 byte). Put the definition of $z into the initialisation of the second for loop (-1 byte). \$\endgroup\$ – Blackhole Sep 4 '15 at 17:00
  • \$\begingroup\$ Save 6 bytes by using the procedural method instead of the object-oriented constructor \$\endgroup\$ – rink.attendant.6 Sep 5 '15 at 3:45
6
\$\begingroup\$

PHP 5.3+, 195 bytes

That includes the newline character.

It's part of the NumberFormatter class, just like razvan's answer. Except I spell out both the cardinals and ordinals according to the ICU.

$f=numfmt_create(en,5);$g=clone$f;$g->setTextAttribute(6,'%spellout-ordinal');for($x=$y='',$i=1;$i++<100;){$x.=$f->format($i).($z=$i<=99?', ':'');$y.=$g->format($i).$z;}echo"One, $x.
First, $y.";

Related: https://stackoverflow.com/a/19411974/404623

\$\endgroup\$
  • \$\begingroup\$ Nice! I had no idea of the %spellout-ordinal format. \$\endgroup\$ – Razvan Sep 5 '15 at 8:09
4
\$\begingroup\$

Oracle SQL 231 bytes

SqlFiddleLiveDemo

 SELECT 'O'||SUBSTR(LISTAGG(TO_CHAR(TO_DATE(level,'j'),'jsp'),', ')WITHIN GROUP(ORDER BY level),2)||'.','F'||SUBSTR(LISTAGG(TO_CHAR(TO_DATE(level,'j'),'jTHSP'),', ')WITHIN GROUP(ORDER BY level),2)||'.' FROM DUAL CONNECT BY level<101
\$\endgroup\$
3
\$\begingroup\$

JavaScript ES6, 562 464 bytes

Not even done golfing yet!

n=>(f=(a,b)=>Array(89).fill(a=btoa(a+`·§·,í*íË7躻rÍø·,ìrÎǯz{rÍè Ü³)Þ·,ó`).split`z`).map((l,i)=>i<1?b:i<20?a[i]:a[18+(i-i%10)/10]+'-'+a[i%10]).join`, `+', one hundred')(`¢w³·
3¶Þ{7躼ß÷³²,s±ëÞ7¢s)ÞÎקÍé^½éó·¥½ìí*íyéó~«µç§Íøµç§Îȱµç§Îǯz{^z|Þmyéó)Þµç§ÎÜܳ¶«·,ߢêíË7â~ܳ²,mË;½éíË7¢rÎx§µì³`,'One')+`
`+f(`~*ì·;rÝÎØb­Üߢêí7â~Øs²,m;½éí7¢Øs)Þ¶íz{aÍé^½éí;pz[Þ¶í*íyéí7躻^z{aÍøµç§¶ì^z{aÎǯz{^z{aÍè ×Øs)޵秶ó`,'First')+'th'

If this doesn't work I might need to add a hexdump because of all the special characters Please let me know if this is the case and I'll get to you by tomorrow.

If they are any typos also let me know.

Code in pastebin (Tested on Safari Nightly)

Explanation

This may look like a bunch of garbled characters but it's actually pretty simple.

We start by generating the cardinals. This array is compressed using the btoa function.

['one', ..., 'eighteen', 'nineteen', 'twenty', 'thirty', ...,'ninety']

To loop through a "range" we use the following:

Now we generate an Array of length 89 using. The ... is what uncompresses the array

Array(89).fill(...)

Then map through it, i is the index:

.map((l,i)=>

Now for the condition, i < 1 or if it is the first item, we will use a capitalized version of one / first

i<1?b

Otherwise... if it is less than 20, we output eleven...nineteen

i<20?a[i]:

Otherwise... using (i-i%10)/10 we get the last digit of the number. We add 18 to it to compensate for 1..19. We add a - and then add the last digit, or i%10

Finally, we add 'one hundred' to the very end because we don't.

We repeat this for both types of numbers and separate with a newline

\$\endgroup\$
  • \$\begingroup\$ Tried with FireFox: the posted code is flawed. The code in pastebin is ok, but misses a period after the first hundred. Overall: great job| +1 \$\endgroup\$ – edc65 Sep 6 '15 at 19:21
  • \$\begingroup\$ What's with the special characters? \$\endgroup\$ – Luminous Sep 9 '15 at 13:46
3
\$\begingroup\$

C++ 704 642 620 602

No library usage other than ostream operator<<() for char*s.

#include<iostream>
char*q,a[]="|one|two|three|four|five|six|seven|eight|ni&u$Il%*twel&bthirte$Q(P#tif#j)/#k'L#|)y#r*4#s'9rst&>cond*5d)zh)gh)U#V)Ch)2h(}#V09$m0M$I0]'g0k)B0|*I#}1A+4$01f+y1u$$|+/nty+(y*`#X*3y)p#V)Ly))y(dyC5~hundred)Oie1o#|1c#}*E#s*a#t*}$&+9#|+T#|+uth",b[448],*s=a,*t=b;int i,j,k;auto p(int k){for(s=b;k--;)while(*s++);return s;}int main(){for(;k=*s++;)if(k>98)*t++=k<'|'?k:" "[k<'~'];else for(i=(k-35)*95+*s++-32,q=t-i/9,k=3+i%9;k--;)*t++=*q++;for(j=0;j<2;++j)for(i=1;b[1+126*j]^=32*(i<3),k=i<20?i:i%10,i<101;++i)std::cout<<p(40+!k*j*11+i/10)<<"-"[!k|i<20]<<p(j*20+k)<<", \0.\n"+i/100*3;}

Live version.

With some whitespace and some comments:

#include <iostream>

// Encoded as literal characters or offset/length pairs for previous runs of characters, LZ like
char *q, a[] =
             "|one|two|three|four|five|six|seven|eight|ni&u$Il%*twel&bthirte$Q(P#tif#j)/"
             "#k'L#|)y#r*4#s'9rst&>cond*5d)zh)gh)U#V)Ch)2h(}#V09$m0M$I0]'g0k)B0|*I#}1A+4$01f+y1u$$|"
             "+/nty+(y*`#X*3y)p#V)Ly))y(dyC5~hundred)Oie1o#|1c#}*E#s*a#t*}$&+9#|+T#|+uth",
         b[448], *s = a, *t = b;

int i, j, k;

// Find the kth null separated string in array b
auto p(int k) {
    for (s = b; k--;)
        while (*s++)
            ;
    return s;
}

int main() {
    // Decode the compressed 'primitives' we use to build up the output.
    for (; k = *s++;)
        if (k > 98)
            *t++ = k < '|' ? k : " "[k < '~'];
        else
            for (i = (k - 35) * 95 + *s++ - 32, q = t - i / 9, k = 3 + i % 9; k--;) *t++ = *q++;

    // Loop twice over numbers 1-100, building up output from the 'primitives' in our array
    for (j = 0; j < 2; ++j)
        for (i = 1; b[1 + 126 * j] ^= 32 * (i < 3), k = i < 20 ? i : i % 10, i < 101; ++i)
            std::cout << p(40 + !k * j * 11 + i / 10) << "-"[!k | i < 20] << p(j * 20 + k)
                      << ", \0.\n" + i / 100 * 3;
}

The compressed string is decoded from a into b:

|one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|
sixteen|seventeen|eighteen|nineteen||first|second|third|fourth|fifth|sixth|seventh|eighth|
ninth|tenth|eleventh|twelfth|thirteenth|fourteenth|fifteenth|sixteenth|seventeenth|
eighteenth|nineteenth|||twenty|thirty|forty|fifty|sixty|seventy|eighty|ninety|one~
hundred|||twentieth|thirtieth|fourtieth|fiftieth|sixtieth|seventieth|eightieth|
ninetieth|one~hundredth;

Without the newlines. During decompression the |s are replaced with '\0' and the ~s are replaced with ' ' (quirk of the way the characters are encoded into printable ASCII). These 'primitive' strings are then looked up by index in the b array using the p function and used to assemble the output.

Compression is a simple LZ like scheme where characters are either encoded as literals or as a negative offset into the buffer and a run length (encoded into two characters) if a match of length >=3 is found. The string could be compressed further using non-printable characters but I like my code to be copy and paste safe :)

\$\endgroup\$
1
\$\begingroup\$

Javascript (ES6), 713

Similar to my second PHP submission on this question. (2444 - 713) / 2444 = 70.8% compression.

a=`Onez]cu^dP~Ntenz\`zHlvezmwgwjwkw{wqwpwHnQxZx]xcxux^xdxPx~xNmQXZX]XcXuX^XdXPX~XNforQbZb]bcbub^bdbPb~bNjQWZW]WcWuW^WdWPW~WNkQVZV]VcVuV^VdVPV~VN{QUZU]UcUuU^UdUPU~UNqQTZT]TcTuT^TdTPT~TNpQSZS]ScSuS^SdSPS~SNy.
FirstzaRMLKJI[ten}\`}Hlf}mGgGjGkG{GqGpGHnYx_xaxRxMxLxKxJxIx[mYX_XaXRXMXLXKXJXIX[forYb_babRbMbLbKbJbIb[jYW_WaWRWMWLWKWJWIW[kYV_VaVRVMVLVKVJVIV[{YU_UaURUMULUKUJUIU[qYT_TaTRTMTLTKTJTIT[pYS_SaSRSMSLSKSJSIS[yth.`,'eleven|`}|`z|twe|q}|{}|k}|j}|g}|pz|{z|kz|gz|one hundred|tyz|mdz|qtz|p~|q~|{~|k~|j~|m~|tie}|onez|nin}|twoz|fivez|firstz|teen|threez|secondz|for~|four|fif|twen~|six|thir|nine|eigh|, |seven|th, |ty-'.split('|').map((e,i)=>a=a.split('`GwHIJKLMNPduyQR~STUVWXYZ[]^_`cabgjxkmpqz{}~'[i]).join(e)),alert(a)

Fiddle

\$\endgroup\$
  • \$\begingroup\$ Why was this downvoted? \$\endgroup\$ – DankMemes Sep 6 '15 at 16:19
1
\$\begingroup\$

Mathematica 415 391 407

The cardinals are given by IntegerName[n]. The ordinals are derived from the cardinals.

s = StringRiffle; y = IntegerName; t = StringReplace;
k@n_ := If[(z = (TextWords["first second third a fifth a a a ninth,a, a twelfth a a a a a eighteenth a, twentieth"])[[n]]) == "a", y@n <> "th", z]
g@n_ := Module[{i = IntegerDigits[n], z}, z := y[Quotient[n, 10]*10];Which[n == 100, "one hundredth", n < 20, k[n], i[[-1]] == 0, t[z, "y" -> "ieth"], 3 > 2, z <> "-" <> k[i[[-1]]]]]
t[(s[y@Range@100 /. "one" -> "One", ", "] <> ".") <> s[g /@ Range@100 /. "first" -> "\nFirst", ", "] <> ".", "tt" -> "t"]

Output:

One, two, three, four, five, six, seven, eight, nine, ten, eleven, twelve, thirteen, fourteen, fifteen, sixteen, seventeen, eighteen, nineteen, twenty, twenty-one, twenty-two, twenty-three, twenty-four, twenty-five, twenty-six, twenty-seven, twenty-eight, twenty-nine, thirty, thirty-one, thirty-two, thirty-three, thirty-four, thirty-five, thirty-six, thirty-seven, thirty-eight, thirty-nine, forty, forty-one, forty-two, forty-three, forty-four, forty-five, forty-six, forty-seven, forty-eight, forty-nine, fifty, fifty-one, fifty-two, fifty-three, fifty-four, fifty-five, fifty-six, fifty-seven, fifty-eight, fifty-nine, sixty, sixty-one, sixty-two, sixty-three, sixty-four, sixty-five, sixty-six, sixty-seven, sixty-eight, sixty-nine, seventy, seventy-one, seventy-two, seventy-three, seventy-four, seventy-five, seventy-six, seventy-seven, seventy-eight, seventy-nine, eighty, eighty-one, eighty-two, eighty-three, eighty-four, eighty-five, eighty-six, eighty-seven, eighty-eight, eighty-nine, ninety, ninety-one, ninety-two, ninety-three, ninety-four, ninety-five, ninety-six, ninety-seven, ninety-eight, ninety-nine, one hundred.
First, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, eleventh, twelfth, thirteenth, fourteenth, fifteenth, sixteenth, seventeenth, eighteenth, nineteenth, twentieth, twenty-first, twenty-second, twenty-third, twenty-fourth, twenty-fifth, twenty-sixth, twenty-seventh, twenty-eighth, twenty-ninth, thirtieth, thirty-first, thirty-second, thirty-third, thirty-fourth, thirty-fifth, thirty-sixth, thirty-seventh, thirty-eighth, thirty-ninth, fortieth, forty-first, forty-second, forty-third, forty-fourth, forty-fifth, forty-sixth, forty-seventh, forty-eighth, forty-ninth, fiftieth, fifty-first, fifty-second, fifty-third, fifty-fourth, fifty-fifth, fifty-sixth, fifty-seventh, fifty-eighth, fifty-ninth, sixtieth, sixty-first, sixty-second, sixty-third, sixty-fourth, sixty-fifth, sixty-sixth, sixty-seventh, sixty-eighth, sixty-ninth, seventieth, seventy-first, seventy-second, seventy-third, seventy-fourth, seventy-fifth, seventy-sixth, seventy-seventh, seventy-eighth, seventy-ninth, eightieth, eighty-first, eighty-second, eighty-third, eighty-fourth, eighty-fifth, eighty-sixth, eighty-seventh, eighty-eighth, eighty-ninth, ninetieth, ninety-first, ninety-second, ninety-third, ninety-fourth, ninety-fifth, ninety-sixth, ninety-seventh, ninety-eighth, ninety-ninth, one hundredth.
\$\endgroup\$
  • 1
    \$\begingroup\$ Some uncorrect eightth \$\endgroup\$ – Mario Trucco Sep 5 '15 at 2:04
  • \$\begingroup\$ You were right! I now corrected them. \$\endgroup\$ – DavidC Sep 5 '15 at 13:03
  • \$\begingroup\$ You could change "first" -> "\nFirst" to "fir" -> "\nFir" to save 4 bytes. \$\endgroup\$ – LegionMammal978 Sep 6 '15 at 12:44
  • \$\begingroup\$ @LegionMamal978, Good suggestion but it won't work because we are replacing elements (words) in a list: "first" is an element in the list, but "fir" is not. If we try to implement your suggestion after the list of elements is StringJoined, then "twenty-first ...thirty-first..." will become "twenty-First...thirty-First...". \$\endgroup\$ – DavidC Sep 6 '15 at 14:00
1
\$\begingroup\$

JavaScript (ES6), 480

/*TEST: redirect console output to snippet body */ console.log=x=>O.innerHTML=x

// Not a function, as a complete program is requested
b=x=>btoa(x).split`/`;
Z=i=>z[i]||z[i-8]||z[i-18];
y=b("ýø«²ßìyÊ'wûa·ýøÿÿÞ)ÿÿûpzWÿÿÿÿÿÿÿ");
z=b("þÞþÜ(þØkyïߢêÿ~+ÞþȱþǯzÞmþx§{û^÷¥z÷§þÜ÷¿¶«ÿ÷âÿÿz(!ÿûpzÿ~ÿÿÿÿ");
o=(z.map((v,i)=>i<20?i<13?v:(v||z[i-10])+'teen':z[S='slice'](0,10).map(d=>Z(i)+(d?'ty-'+d:'ty')))+`,${h='one hundred'}.\nF`).split`,`;
q=y.map((v,i)=>i<4?v:`${v||o[i]}th`);
q=z.map((v,i)=>i<20?' '+q[i]:q[S](0,10).map(d=>' '+Z(i)+(d?'ty-'+d:'tieth')));
console.log('O'+o.join`, `[S](3)+`${q}, ${h}th.`[S](4))

// INFO: z uncompressed is [,one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thir,,fif,,,eigh,,twen,,for,,,,,]
// INCO: y uncompressed is [,first,second,third,,fif,,,eigh,nin,,,twelf,,,,,,,,,]
#O { white-space: pre-wrap }
<pre id=O></pre>

\$\endgroup\$
0
\$\begingroup\$

PHP - 842 bytes

Omitting regular PHP starting and ending tags, compression is 1 - 842/2445 = 65.6%

Basically getting the output of base64_encode(gzdeflate($input, 9)); and reversing the operations. Obviously, if I chose to output in pure 8-bit vs. base-64, it would be 25% smaller, but at the risk of running into escape or non-printable characters.

echo gzinflate(base64_decode('VZRdcuIwEITfcwoOQHKMfd1DBGnlKspUEYfEt1+rf2bGL6gbkLplS9/ftV0v28/j+BjPduj++H4en8vr0F/L7/HRXm29Xtryb2zXy7pgAr6585ftp93nv7exPLc2v5lrSC2d4lhKYk6ixJJQc1WqY7F12z2+P1gPmi2lWVaOnW1QXQY7sI6602k/ctrW3MHuUeHUekTUCqdTuMzyyl8YLq1wOofTMbw/kI2B0ZRIlvQrylxpxFIjVZKhNMqkUeTxdnYNioRkJKUiYXw2ekZCM5JSkTCOhGHkPAe7BkZSIlKSkTSMlPahdKQkI2kUSaNInLg9hGJlGGyjaFmF2zFeLu9GqSDrErKsgS93jywhjQ7WrCDHBjYoIIN863JFI12O4bhgu0eGSyPcmuFyDLdBuAzCrRkuVzAR4UfaZXyvt2e7fbz9WZ5feDafj/XGK3ATMQaPyuDrG36AQ3sZWHYOm769+/eJIEw0g7CWKOR1JUWiXL+VDGnzSGuv29JCzkeBLQRWtBOTCRsqZDrN7MVplxVPxXvPSajYoNoYOWxjzuRzLW0SVaeZvTi3KbwqPtoEsviIXcYcQhfTh1XMLr3oWsSzehrVKABL6xLBML9adRCY2EE4UgfBjB0CZnVWT+MOSbS00cFQ85liB5OKh1x8YgfTDR2SbnVWT+MrkIhL6w5BuTzMahHI0mV7nY5q4o5dCu7Os3u1p0tZO1XqjRP24l6xVnAMrQJeLBX8Q6fCv9PMXpwKVQgW7zrJwbjZbBNgQ5ugGdsEENGmAPE0sxenNpWKxReCtWxTyLiNj7f/'));
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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