...Ordinal numbers (or ordinal numerals) are words representing position or rank in a sequential order.

enter image description here

From Wikipedia.

Your task is, using 2 separate programs (of which can be made from 2 different languages), to output the ordinal sequence from first to nth. You will be outputting the full word second as opposed to 2nd.

The challenge of ordinal numbers has been brought up before, particularly in this entry. In this challenge, ordinals are merely a vehicle to facilitate the unique conditions detailed below.

Part 1

You must make a program that, when given the input of n must output anything.
n will always be a positive, non-zero integer no larger than 999.

Valid output includes but is not limited to:

  • Any output to stdout / stderr / etc
  • Creation of files / folders / etc
  • A graphical interface or images of any kind

Anything goes.

Part 2

You must make a program that uses the output of part 1's program to output a sequence of ordinal numbers, starting from 1 (first), up to whatever n was parsed in part 1.

General Conditions:

  • The total bytes for part 2 must not exceed the total bytes for part 1 (less than or equal to).

Output conditions:

  • Not case sensitive.
  • Output must contain only the ordinal sequence (only characters a-Z) and whitespace (newlines allowed).
  • Can be output to any source, so long as it is visible either during or after execution.
  • Program does not need to terminate so long as its output is correct.
  • Output is not required to have any grammar, but may optionally include it (hyphens, commas, "ands", etc). nine hundred ninety ninth is just as acceptable as nine hundred and ninety-ninth.

Sample Output

Where n is 8



The hierarchy of win conditions is:

  1. The lowest number of bytes in part 1
  2. The lowest number of bytes in part 2
Entry #1 | Part 1 = 32 bytes, Part 2 = 22 bytes
Entry #2 | Part 1 = 31 bytes, part 2 = 30 bytes

Entry #2 wins - Part 1 contains 31 bytes vs 32 bytes


Entry #1 | Part 1 = 21 bytes, Part 2 = 33 bytes
Entry #2 | Part 1 = 80 bytes, Part 2 = 70 bytes

Entry #2 wins - Entry #1 disqualified (Part 2 contains more bytes than Part 1)


Entry #1 | Part 1 = 50 bytes, Part 2 = 49 bytes
Entry #2 | Part 1 = 50 bytes, Part 2 = 50 bytes

Entry #1 wins - Part 1 is equal, Part 2 contains 49 bytes vs 50 bytes
  • 5
    \$\begingroup\$ What's the point in part 1 (as in, why couldn't this challenge just be scored on shortest submission for part 2)? Also, in your second scoring example, isn't the first entry invalid (part 2 > part 1), and if not, wouldn't it beat the second entry? Also, I recommend having at least a link to a formal ruleset for defining ordinals; for example, is 111 supposed to say one hundred and eleventh or one hundred eleventh? \$\endgroup\$
    – hyper-neutrino
    Jul 15, 2019 at 1:02
  • 3
    \$\begingroup\$ @HyperNeutrino I think the idea is to try to split the work between the two as evenly as possible while golfing -- if I make p1 output [30, 'second'] for 32 then p2 has less work to do that if it had output, just 32. \$\endgroup\$ Jul 15, 2019 at 1:09
  • 4
    \$\begingroup\$ Maybe I'm missing something stupid, but of the last two entries in the scoring examples, why doesn't entry 1 win? part 1 has same bytes, part 2 is less than or equal to part 1 for both, and entry 1 part 2 has less bytes than entry 2 part 2. \$\endgroup\$ Jul 15, 2019 at 9:02
  • \$\begingroup\$ @PatrickRoberts Because Part 2 must contain equal or fewer bytes to Part 1. Since Part 1 is 21 bytes, but Part 2 is 33 bytes, Entry #1 is disqualified. Unfortunately, that information is tucked away and not explicitly stated in the win conditions at the moment. \$\endgroup\$ Jul 15, 2019 at 11:38
  • \$\begingroup\$ @PatrickRoberts This is important, because otherwise you could use a language that implicitly passes input as output when a 0 byte program is run for Part 1 \$\endgroup\$ Jul 15, 2019 at 11:43

7 Answers 7


Sledgehammer 0.5.1 / Sledgehammer 0.5.1, 10 bytes

Program 1 (10 bytes):


Decompresses into this Wolfram Language function:

{Range[#1], "Ordinal"} &

Program 2 (7 bytes):


Decompresses into this Wolfram Language function:

StringRiffle[IntegerName @@ #1, " "] &

Try it online!


R (with english package), 16 bytes / 16 bytes

 Part 1, 16 bytes


Part 2, 16 bytes


Requires the english package (which is not installed on TIO, unfortunately).

english::ordinal(f(22)) outputs first second third fourth fifth sixth seventh eighth ninth tenth eleventh twelfth thirteenth fourteenth fifteenth sixteenth seventeenth eighteenth nineteenth twentieth twenty first twenty second.

Of course, part 1 could be made much shorter (3 bytes: seq), but that would go against the constraint that part 2 has to be no longer than part 1.

  • \$\begingroup\$ @Giuseppe Sure. Although I would argue that CRAN packages are part of R, and so should be allowed as long as we count the characters needed to load and attach them. \$\endgroup\$ Jul 16, 2019 at 20:07
  • \$\begingroup\$ I believe meta consensus is that using an external library essentially counts as "another language"; see for instance this post which is about compiler flags, but has a note about Python external libraries. The answer here is instructive with many examples but I can't seem to use the search function on meta to find the definitive statement. \$\endgroup\$
    – Giuseppe
    Jul 16, 2019 at 21:21
  • \$\begingroup\$ @Giuseppe Continued in chat: chat.stackexchange.com/transcript/message/51052875#51052875 \$\endgroup\$ Jul 17, 2019 at 8:06

Wolfram Language (Mathematica) (both parts), 18 bytes / 15 bytes

-5/-1 thanks to lirtosiast

Part 1, 18 bytes


Part 2, 15 bytes


Try it online!

Two functions which output via return value.

  • 2
    \$\begingroup\$ Range@#|"Ordinal"& is shorter, and IntegerName vectorizes over the first argument. I think space-separated output might be required, though. \$\endgroup\$
    – lirtosiast
    Jul 15, 2019 at 4:33

Python 3(part 1 & part 2)

Unfortunately Nodebox is very wordy... there is not much room for golfing.

Part 1 76 bytes

for  i  in  range  (  1 ,  int  (  input  (  ) ) + 1 ) : print ( i ,end=" ")

Part 2 (Uses the NodeBox library) 76 bytes

import en.number as n
for i in input().split():print(n.ordinal(n.spoken(i)))
  • 5
    \$\begingroup\$ Your answer must be valid; in this case, your part 2 is longer than your part 1, which is invalid. You cannot mark an answer as "non-competing" and submit an invalid submission; the "non-competing" label is a deprecated label for challenges submitted in languages or language versions that postdate the challenge, which used to be typically disallowed, but allowed under "non-competing" status for interesting submissions anyway. \$\endgroup\$
    – hyper-neutrino
    Jul 15, 2019 at 2:52
  • 1
    \$\begingroup\$ @HyperNeutrino Sorry, I thought the rules required Part 1 to be shorter than Part 2. I marked this as non-competing because it used a library to solve this problem. \$\endgroup\$
    – user85052
    Jul 15, 2019 at 2:59
  • 2
    \$\begingroup\$ Technically, using external libraries seems to be alright: codegolf.meta.stackexchange.com/q/188 \$\endgroup\$
    – lyxal
    Jul 15, 2019 at 3:41
  • 1
    \$\begingroup\$ import en.number as n saves you four bytes in each part. \$\endgroup\$ Jul 15, 2019 at 21:41

JavaScript (Node.js), 47 bytes / 47 bytes

Two functions in the same Node.js environment, invoked like g(f(n)). Uses the npm package number-to-words.

Part 1, 47 bytes (40 bytes + 7 spaces)


Part 2, 47 bytes


Try it on Runkit!

JavaScript (Node.js), 48 bytes / 43 bytes

Part 1, 48 bytes


Part 2, 43 bytes


Try it on Runkit!


Perl 5.10 / Common Lisp, 34 / 26 bytes

So, Common Lisp format has this as a built-in, because of course it does.

Program 1 (34 bytes)

say"(format t\"~:r \"$_)"for 1..<>

Perl does all the iterating. The equivalent Common Lisp code ((dotimes(i(read)) ...)) is longer than the much golfier Perl ... for 1..<>. Perl outputs a bunch of Common Lisp code.

Program 2 (26 bytes)

(loop(eval(read nil nil)))

It's a REPL, minus the P. It reads standard input and, well, executes it. Doesn't terminate, but the rules explicitly say that's fine.


Vyxal, 2/2 bytes

ɾ, # print range (1,n+1)
∆o # nth ordinal of each

Try it Online!


Your Answer

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

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