47
\$\begingroup\$

I would like to generate (as a return result of a function, or simply as the output of a program) the ordinal suffix of a positive integer concatenated to the number.

Samples:

1st  
2nd  
3rd  
4th  
...  
11th  
12th  
13th  
...  
20th  
21st
22nd
23rd
24th

And so on, with the suffix repeating the initial 1-10 subpattern every 10 until 100, where the pattern ultimately starts over.

The input would be the number and the output the ordinal string as shown above.

What is the smallest algorithm for this?

\$\endgroup\$
  • \$\begingroup\$ Hi, NickC, and welcome to codegolf.SE! Just to clarify, do you mean that we should read a number like 11 as input, and output e.g. 11th? Is each number in the input on a separate line, and should the output numbers be on separate lines too? And do we need to handle more than one line of input? \$\endgroup\$ – Ilmari Karonen Jan 20 '12 at 18:26
  • 1
    \$\begingroup\$ Are you looking for smallest algorithm or smallest code? \$\endgroup\$ – Toto Jan 20 '12 at 18:31
  • \$\begingroup\$ @Ilmari I am looking for 11 as input and 11th as output. I don't mind if it processes multiple lines but what I had in mind was processing just a single number. \$\endgroup\$ – Nicole Jan 20 '12 at 21:00
  • \$\begingroup\$ @M42 You know, I'm not really sure. I don't have a strict requirement - but I was probably thinking smallest algorithm. \$\endgroup\$ – Nicole Jan 20 '12 at 21:02

41 Answers 41

1
2
1
\$\begingroup\$

Python, 88 84 bytes

lambda x:x+((('th','st','nd','rd')+('th',)*6)[int(x[-1])]if('0'+x)[-2]!='1'else'th')

Ungolfed:

def y(x):
    return x + (('th', 'st', 'nd', 'rd') + ('th', ) * 6)[int(x[-1])] if ('0' + x)[-2] != '1' else 'th')

lambda x defines an anonymous function with parameter x. ((('th','st','nd','rd')+('th',)*6)[int(x[-1])] defines a tuple of the endings for numbers less than 10, the 0-th element is for 0, and so forth. the if ('0'+x)[-2] != '1' checks if there is 11, 12, or a 13 to fix, and adds then else 'th' adds th instead of st, rd, or nd.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ This is a great answer, but it took me a while to go through and understand it. If you could add a code explanation and breakdown below the golfed version of your code, it would help people learn from your code and improve the quality of your answer. \$\endgroup\$ – wizzwizz4 Feb 25 '16 at 17:06
  • \$\begingroup\$ Ok, I will. Should I also add an un-golfed answer? \$\endgroup\$ – NoOneIsHere Feb 25 '16 at 17:31
  • \$\begingroup\$ It shouldn't be a different answer... What you've done is fine, well done. If you want any more challenges to do, I could give some recommendations. \$\endgroup\$ – wizzwizz4 Feb 25 '16 at 17:53
  • \$\begingroup\$ Ok. You could try... Adjust your chair, or Where will your buddies sit. Or you could try some of my challenges, such as The Knight's Next Tour. If these aren't the sort of challenges you like, just say. \$\endgroup\$ – wizzwizz4 Feb 25 '16 at 18:08
1
\$\begingroup\$

Scala 2.11.7, 151 Chars

def o(x:Int*)=x map{
case a if(a%10)==1&&a%100!=11=>a+"st"
case b if(b%10)==2&&b%100!=12=>b+"nd"
case c if(c%10)==3&&c%100!=13=>c+"rd"
case e=>e+"th"
}

Usage

   o(1,2,3,4) -> ArrayBuffer("1st", "2nd", "3rd", "4th")
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Sorry, but all answers need to be golfed. Please golf this, if not than it's invalid and must be deleted. \$\endgroup\$ – Rɪᴋᴇʀ Sep 23 '16 at 12:53
  • \$\begingroup\$ I'm pretty sure you can remove the space between map and {, : and Int*, and remove the newline between "th" and } (I don't know Scala, so I might be completely wrong). Welcome to PPCG! \$\endgroup\$ – clismique Sep 28 '16 at 6:13
1
\$\begingroup\$

Java 7, 91 81 bytes

String d(int n){return n+(n/10%10==1|(n%=10)<1|n>3?"th":n<2?"st":n<3?"nd":"rd");}

Port from @adrianmp's C# answer.

Old answer (91 bytes):

String c(int n){return n+((n%=100)>10&n<14?"th":(n%=10)==1?"st":n==2?"nd":n==3?"rd":"th");}

Ungolfed & test code:

Try it here.

class M{
  static String c(int n){
    return n + ((n%=100) > 10 & n < 14
                ?"th"
                : (n%=10) == 1
                   ? "st"
                   : n == 2
                      ? "nd"
                      : n == 3
                         ? "rd"
                         :"th");
  }

  static String d(int n){
    return n + (n/10%10 == 1 | (n%=10) < 1 | n > 3
                 ? "th"
                 : n < 2
                    ? "st"
                    : n < 3
                       ? "nd"
                       :"rd");
  }

  public static void main(String[] a){
    for(int i = 1; i < 201; i++){
      System.out.print(c(i) + ", ");
    }
    System.out.println();
    for(int i = 1; i < 201; i++){
      System.out.print(d(i) + ", ");
    }
  }
}

Output:

1st, 2nd, 3rd, 4th, 5th, 6th, 7th, 8th, 9th, 10th, 11th, 12th, 13th, 14th, 15th, 16th, 17th, 18th, 19th, 20th, 21st, 22nd, 23rd, 24th, 25th, 26th, 27th, 28th, 29th, 30th, 31st, 32nd, 33rd, 34th, 35th, 36th, 37th, 38th, 39th, 40th, 41st, 42nd, 43rd, 44th, 45th, 46th, 47th, 48th, 49th, 50th, 51st, 52nd, 53rd, 54th, 55th, 56th, 57th, 58th, 59th, 60th, 61st, 62nd, 63rd, 64th, 65th, 66th, 67th, 68th, 69th, 70th, 71st, 72nd, 73rd, 74th, 75th, 76th, 77th, 78th, 79th, 80th, 81st, 82nd, 83rd, 84th, 85th, 86th, 87th, 88th, 89th, 90th, 91st, 92nd, 93rd, 94th, 95th, 96th, 97th, 98th, 99th, 100th, 101st, 102nd, 103rd, 104th, 105th, 106th, 107th, 108th, 109th, 110th, 111th, 112th, 113th, 114th, 115th, 116th, 117th, 118th, 119th, 120th, 121st, 122nd, 123rd, 124th, 125th, 126th, 127th, 128th, 129th, 130th, 131st, 132nd, 133rd, 134th, 135th, 136th, 137th, 138th, 139th, 140th, 141st, 142nd, 143rd, 144th, 145th, 146th, 147th, 148th, 149th, 150th, 151st, 152nd, 153rd, 154th, 155th, 156th, 157th, 158th, 159th, 160th, 161st, 162nd, 163rd, 164th, 165th, 166th, 167th, 168th, 169th, 170th, 171st, 172nd, 173rd, 174th, 175th, 176th, 177th, 178th, 179th, 180th, 181st, 182nd, 183rd, 184th, 185th, 186th, 187th, 188th, 189th, 190th, 191st, 192nd, 193rd, 194th, 195th, 196th, 197th, 198th, 199th, 200th, 
1st, 2nd, 3rd, 4th, 5th, 6th, 7th, 8th, 9th, 10th, 11th, 12th, 13th, 14th, 15th, 16th, 17th, 18th, 19th, 20th, 21st, 22nd, 23rd, 24th, 25th, 26th, 27th, 28th, 29th, 30th, 31st, 32nd, 33rd, 34th, 35th, 36th, 37th, 38th, 39th, 40th, 41st, 42nd, 43rd, 44th, 45th, 46th, 47th, 48th, 49th, 50th, 51st, 52nd, 53rd, 54th, 55th, 56th, 57th, 58th, 59th, 60th, 61st, 62nd, 63rd, 64th, 65th, 66th, 67th, 68th, 69th, 70th, 71st, 72nd, 73rd, 74th, 75th, 76th, 77th, 78th, 79th, 80th, 81st, 82nd, 83rd, 84th, 85th, 86th, 87th, 88th, 89th, 90th, 91st, 92nd, 93rd, 94th, 95th, 96th, 97th, 98th, 99th, 100th, 101st, 102nd, 103rd, 104th, 105th, 106th, 107th, 108th, 109th, 110th, 111th, 112th, 113th, 114th, 115th, 116th, 117th, 118th, 119th, 120th, 121st, 122nd, 123rd, 124th, 125th, 126th, 127th, 128th, 129th, 130th, 131st, 132nd, 133rd, 134th, 135th, 136th, 137th, 138th, 139th, 140th, 141st, 142nd, 143rd, 144th, 145th, 146th, 147th, 148th, 149th, 150th, 151st, 152nd, 153rd, 154th, 155th, 156th, 157th, 158th, 159th, 160th, 161st, 162nd, 163rd, 164th, 165th, 166th, 167th, 168th, 169th, 170th, 171st, 172nd, 173rd, 174th, 175th, 176th, 177th, 178th, 179th, 180th, 181st, 182nd, 183rd, 184th, 185th, 186th, 187th, 188th, 189th, 190th, 191st, 192nd, 193rd, 194th, 195th, 196th, 197th, 198th, 199th, 200th, 
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Common Lisp, 63

(format t"~a~a"i(let((x(format()"~:r"i)))(subseq x(-(length x)2))))

Input is i. There's probably a more clever way to golf this.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Pyth, 33 bytes

+Q@.>+c"stndrd"2*]"th"7 1?qh`Q\1Z

Try it online!

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Procedural Footnote Language, 39 bytes

[1]
[PFL1.0]
[1] [ORD:[INPUT]]
[PFLEND]

The BODY section of the document contains a reference to footnote [1]; footnote [1] contains the [ORD]inal representation of the [INPUT].

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

JavaScript (Node.js), 51 bytes

credit to @KevinCruijssen for improving the answer

n=>n+=[,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th'

Try it online!


Explanation :

n =>                      // input
    n+=[,'st','nd','rd']     // the array of suffices add everything to n
        [~~(n/10%10)-1?n%10:0] // the full magic 
    || 'th'               // works for everything except 1 , 2 , 3 just like what you want

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ "The full magic". The one bit I actually wanted to read the comments on :) \$\endgroup\$ – Steve Bennett May 5 at 13:19
  • \$\begingroup\$ @SteveBennett The general logic that if the tens digit ((n/10%10), rounded by the ~~) is a one (-1) then just get the index 0, which maps to th, otherwise get the index of the ones digit, which will be the appropriate suffix for 1,2 and 3, and th otherwise \$\endgroup\$ – Jo King Jul 12 at 7:02
1
\$\begingroup\$

Julia 0.6, 68 bytes

f(x,m=x%10,p=x%100-m)="$x$(["th","st","nd","rd"][m>3||p==10?1:m+1])"

Try it online!

Straightforward remainder rules in Julia.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

APL(NARS), 38 chars, 76 bytes

(⍕,{((⍳3)⍳10∣⍵×3≠⌊√⍵)⊃'snrt',¨'tddh'})

test:

  h←(⍕,{((⍳3)⍳10∣⍵×3≠⌊√⍵)⊃'snrt',¨'tddh'})
  h¨0..19
 0th 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 
  h¨20..31
 20th 21st 22nd 23rd 24th 25th 26th 27th 28th 29th 30th 31st 
  ⎕fmt h¨100..104
┌5───────────────────────────────────────────┐
│┌5─────┐ ┌5─────┐ ┌5─────┐ ┌5─────┐ ┌5─────┐│
││ 100th│ │ 101st│ │ 102nd│ │ 103rd│ │ 104th││
│└──────┘ └──────┘ └──────┘ └──────┘ └──────┘2
└∊───────────────────────────────────────────┘
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ I don't think you need the outermost parens (or is it a weak point of NARS?) \$\endgroup\$ – Bubbler Jul 13 at 23:12
  • \$\begingroup\$ @Bubbler I remember without parentesis () does not assign to "h" name \$\endgroup\$ – user58988 Jul 15 at 8:15
  • \$\begingroup\$ for me is ok in that way \$\endgroup\$ – user58988 Jul 15 at 8:17
0
\$\begingroup\$

05AB1E, 21 bytes

т%T‰ć≠*4ªß…thŠØ3ôs訫

Try it online or verify a few more test cases at once.

Explanation:

Mostly ported from a sub-section of this answer of mine, except with additional leading т%.

т%                     # Take modulo-100 on the (implicit) input-integer
  T‰                   # Take the divmod-10 ([n//10,n%10]) on that
    ć                  # Extract the head: n//10
     ≠                 # Check that it's NOT equal to 1 (0 if 1; 1 otherwise)
      *                # Multiply the [n%10] by this
       4ª              # Append a 4 to this list: [n%10*(n//10!=1),4]
         ß             # Pop and push the smallest number in this list
          …thŠØ        # Push dictionary string "th standards"
               3ô      # Split it into parts of size 3: ["th ","sta","nda","rds"]
                 sè    # Index the calculated minimum into this list
                       # (modular 0-based, so both 0 and 4 will index into "th ")
                   ¨   # Remove the last character
                    «  # And append it to the (implicit) input-integer
                       # (after which the result is output implicitly)

See this 05AB1E tip of mine (section How to use the dictionary?) to understand why …thŠØ is "th standards".

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

FEU, 34 bytes

m/1(.)$/1\1th/1$/1st/2$/2nd/3$/3rd

Try it online!

| improve this answer | |
\$\endgroup\$
1
2

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.